(function() {
	//空选项功能，如果浏览器支持placeholder，则使用原生placeholder， 否则脚本模拟
	var canPlaceholder = 'placeholder' in document.createElement('input');
		
	//模拟placeholder，需要付出代价，取val()值需要判断是否是提示值，如果是提示值，则也返回空，因此封装了validVal函数获取值
	$.fn.validVal = canPlaceholder ? $.fn.val : function(){
		var value = this.val();
		return value == this.data("addEmptyOption") ? "" : value;
	}
	var dropdown = {
		//全局自增序号
		index:0,
		//初始化selector
		setSelector : function(input, selector, op) {
			var id = input.id();
			if (!id) {
				id = 'dropdown_' + (this.index++) + '';
				input.id(id);
			}
			selector.data("callerId",id); 
			id += '_ddl';
			
			selector.id(id).data('op', op); 
//			if(op.container){
//				selector.appendTo(op.container);
//				op.container = null;
//			}
//			else 
			if(op.appendAfter)//是否添加到input之后
			{
				selector.insertAfter(input);
				op._offset = 'position';
			}
			else //添加到ccay的页面内容容器
			{
				selector.appendTo(Ccay.UI.getPopupPanel());
				op._offset = true;
			}
			//注册销毁事件
			input.bindDestory(function(){				
				var poper = dropdown.getSelector($(this));
				poper.length && poper.remove();
			});
			op.richMode || this.bindSelectorClick(selector,op);
			op.allowDel && this.bindSelectorHover(selector,op);
			
			//多选时全选显示文本
			if(!op.emptyText && op.multi)
				op.emptyText = "ccay.common.dropdown.all";
			
			var head = $.create('div','ccay-selector-head').appendTo(selector);
			//空项设置
			if(op.emptyText || (op.addEmptyOption && !op.multi))
			{
				op.emptyText === true && (op.emptyText = "ccay.common.dropdown.empty");
				$.create('div','ccay-selector-empty' + (op.multi ? ' ddl-multi' : '')).text($i18n(op.addEmptyOption || op.emptyText )).appendTo(head).click(function(e){
					dropdown.cancelClick(e);
					if(op.multi){
						dropdown.selectedAll(input,selector,op,$(this).toggleClass('ddl-selectAll').hasClass('ddl-selectAll'))
					}else{
						dropdown.selected(op, '', op.addEmptyOption && !canPlaceholder ? op.addEmptyOption : '', null, selector, input)
					}
				});
			}
			$.create('div','ccay-selector-body').appendTo(selector);
			$.create('div','ccay-selector-foot').appendTo(selector);
			op.fnBuildSelector && op.fnBuildSelector(selector,op);
			return '#' + id;
		},
		//清空selector
		clearSelector:function(selector){
			this.getSelectorBody(selector).empty();
		},
		//根据input获取selector
		getSelector:function(input){
			return $(input.data("selector"));
		},
		getSelectorBody:function(selector){
			return selector.children('.ccay-selector-body');
		},
		//根据selector、trigger等获取input
		getInput : function(trigger) {
			trigger = $(trigger);
			if (!trigger.hasClass('ccay-dropdown')) {
				var input;
				if (trigger.hasClass('ccay-selector'))
				{//selector获取input
					var input = trigger.data('input'); 
					if(!input)
					{
						var id = trigger.id();
						input = $('#' + id.substr(0, id.length - 4))
					}
				}
				else//trigger获取input
					input = trigger.prevAll('.ccay-dropdown:first');

				return input;
			}
			return trigger;
		},
		setCombobox : function(input, op) {
			input.hasClass('ccay-combobox') || input.addClass('ccay-combobox');
			//注册键盘过滤事件
			//op.fnMatchInput && Ccay.UI.delayEvent2(input, 'keyup', op.fnMatchInput, op.delay,Ccay.UI.isKeyDownValue);
			// 修复下拉框选择数据回车 再次弹出下拉数据。
			op.fnMatchInput && Ccay.UI.delayEvent2(input, 'keyup', op.fnMatchInput, op.delay,function(e, trigger){
				return Ccay.UI.isKeyDownValue(e, trigger) && e.keyCode != 13;
			});
		},
		//取消click冒泡
		cancelClick : function(e,isClose) {
			if (e){
				//e.stopPropagation();
			}
		},
		cancelClick1 : function(e,isClose) {
			if (e){
				e.stopPropagation();
			}
		},
		//键盘操作事件
		keydown : function(e) {
			var input = $(this), selector = dropdown.getSelector(input), op = selector.data('op'),haschange,haschangeTime;
			var trigger= dropdown.getTrigger(input);
			//针对没有trigger的联想控件，如果输入值后，则不显示历史记录图标，清空后，显示历史记录图标
			if(trigger.hasClass("history") && Ccay.History.hasHistory(op) ){
				setTimeout(function(){
					if(input.validVal()){
						trigger.addClass("hide");
					}else{
						trigger.removeClass("hide");
					}
				},0);
			}
			setTimeout(function(){
				input.data("lastFocusIndex",Ccay.UI.getInputFocus(input));
			},0);
			//联想框验证与提示优化-------add by chenzhiwu ,相应按键事件后，判断value是否有改动，如果有，则记录状态 
			if(op._type == 'sgt' ){
				var oldvalue = input.data("oldvalue");
				if(input.validVal() !== oldvalue ){
					haschange = true;
					input.data("oldvalue",input.validVal()).data("haschanged",true);
				}
				if(!haschange){
					haschangeTime = setTimeout(function(){
						if(input.validVal() !== oldvalue ){
							input.data("oldvalue",input.validVal()).data("haschanged",true);
						}
					})
				}
			}
			//------------- end--------------;
			if (selector.length) {
				input.hasClass("error-ctr") && input.clearValid();
				//记录键位的焦点
				op.sgtMulti && suggestion.cacheFocus(input);
				var keyCode = e.keyCode;
				if ((keyCode == 38 || keyCode == 40) && selector.isVisiable()) {//上下操作
					var currentItem = selector.find('.' + op.preSelected), selectedItem;
					if (currentItem.length == 0) {
						selectedItem = selector.find('.' + op.itemClass+ ':visible:'+ (e.keyCode == 38 ? 'last' : 'first'));
					} else {
						currentItem.removeClass(op.preSelected);
						if (keyCode == 38) {
							selectedItem = currentItem.prevAll(':visible:first');
							if (selectedItem.length == 0)
								selectedItem = selector.find('.' + op.itemClass + ':visible:last');
						} else {
							selectedItem = currentItem.nextAll(':visible:first');
							if (selectedItem.length == 0)
								selectedItem = selector.find('.' + op.itemClass + ':visible:first');
						}
					}
					if(selectedItem.length){
						selectedItem.addClass(op.preSelected);
						//处理滚动条效果
						var top = selectedItem.position().top,body = selector.find(op.scrollBody);
						if(top){
							//debugger;
							var height = selectedItem.outerHeight() + top - body.height();
							height && body.scrollTop(height + body.scrollTop() + 100);
						}
						else
							body.scrollTop(0);
					}	
					return false;
				} else if (keyCode == 13 || keyCode == 9) {
					//回车事件和tab事件
					if(keyCode === 13){
						dropdown.clearInterval(op);
					}
					keyCode != 9 && e.stopPropagation();
					var op = selector.data('op'),
						item = selector.find(':not(.hide).' + op.preSelected + ':first');
					
					if (selector.isVisiable() && item.length && keyCode == 13) {
						//选择操作
						if (!op.multi)
							selector.hide();
						haschangeTime && window.clearTimeout(haschangeTime);
						if (op.fnKeyEnter)
							op.fnKeyEnter(item,input,selector,op);
						else
							!input.data("INPUTING") && dropdown.itemSeleted(selector,item,op);
					
						//op._type == 'sgt' && input.data("called",1);
					} else {//填出选择框
						if(input.validVal().length || keyCode == 9){
							//Ccay.Core.log(input.data('called'));
							if (!input.data("called") && op.fnCallSelector){
								input.data('called',1);
								op.fnCallSelector.call(input);
							}
						}
						else
						{
							var trigger = dropdown.getTrigger(input);
							trigger.length && trigger.click();
						}
					}
					if (keyCode === 13 && input[0].tagName == "TEXTAREA")
						return false;
				}
				else
				{
					//联想框联想关键字在非静态匹配下，隐藏下拉菜单
					if(op._type == 'sgt' && Ccay.UI.isKeyDownValue(e)) 
					{
						!selector.data('cached') && selector.hide().children('.ccay-selector-foot').hide();
					}
				}
			}
		},
		//设置selector宽度
		setWidth : function(selector, op,input) {
			//debugger;
//			if(input[0]!==document.activeElement)
//				return;
			var child = selector.find('.list');
			if(child.length){
				if(!input)
					input = this.getInput(selector);
				var childWidth = child.width(), 
					inputWidth = input.outerWidth()-2,
					minWidth = inputWidth > op.minWidth ? inputWidth : op.minWidth;
				if(op.overflow)	{
					selector.width(minWidth);
					minWidth = child.height() > selector.height() ? minWidth - 25 : minWidth;
					selector.find('.list .list-item').each(function(){
						$(this).attr("title",$(this).text()).width(minWidth);
					})
					child.width(minWidth);
				}else{
					var width = Ccay.DataHelper.getRangeValue(childWidth, minWidth, op.maxWidth);
					if (child.height() > selector.height()){
					//当有滚动条效果时，预留滚动条宽度
						if(childWidth > inputWidth - 17){
					selector.width(width + 17);
							child.width(width);
						} else{
							 selector.width(width);
							 child.width(width- 17);
						}
					}
					else{
					selector.width(width);
				if (width > childWidth)
					child.width(width);
					}
				}
			}
			var height = child.outerHeight(),body = this.getSelectorBody(selector);
			if(height && child.width() > body.width())
				height += 20;
			body.height(height+1 || "auto");
		},
		
		mergeHistory : function(op,datas,input,isLdap){
			if(!this.checkHistorySupport(op)){
				return datas;
			}
			var validHistory = [],history = Ccay.History.getHistory(op.historyKey || ( op.ajax && op.ajax.url )); 
			if(history.length == 0){
				return datas;
			}
			//将历史数据，与查询出来的数据进行比较，如果存在，则为有效的数据，并添加到validhistory中，最后合并到datas中
			var cacheKey = {},historyCacheKey = {};
			datas && $.each(datas,function(){
				cacheKey[this[op.valueField]] = this;
			})
			
			$.each(history,function(){
				historyCacheKey[this.value] = true;
				var record = cacheKey[this.value];
				if(record){
					//作为历史选项，添加一个标识
					validHistory.push($.extend({_history :"history-item" },record))
				}else if(this.data && op._type == 'sgt' && (isLdap || datas.length == op.suggestNum)){
					//作为历史选项，添加一个标识
					this.data._history = "history-item";
					this.data._novalid = true;
					validHistory.push(this.data)
				}
			});
			
			if(validHistory.length > 0){
				$.each(datas, function(){
					if(!historyCacheKey[this[op.valueField]]){
						validHistory.push(this)
					}
				});
				return validHistory;
			}else{
				return datas;
			}
			
		},
		
		//suggest模式验证历史选项有效性
		validSgtHistory : function(value,op,callback,input){
			if(op.getTextAjax){
				dropdown.ajax($.extend({type:"POST"},op.getTextAjax,{
					data : [value],
					success:function(datas){
						input.data("called",0);
						callback && callback(datas && (!$.isArray(datas) || datas.length > 0) ? true :false);
					},
					error :function(){
						input.data("called",0);
						callback && callback(false);
						return true;
					}
				}),input);
			}else{
				callback(true);
			}
		},
		//判断是否支持历史选项记录功能
		checkHistorySupport : function(op){
			return !op.richMode && !op.sgtMulti  && Ccay.History.isSupport(op);  //去掉下拉框是否为多选的判断（!op.multi）
		},
		//生成选择项
		buildSelector : function(selector, datas, op, needvalid) {
		  
			if (!op)
				op = selector.data('op');
			if(op){
				if(datas.length > op.suggestNum){
					datas =  datas.slice(0, op.suggestNum); 
				}
				var input = this.getInput(selector);
				input.removeData("haschanged");
				//历史记录合并 hisotry
				if(datas.length > 1 && !datas[0]._history) { 
					 datas = dropdown.mergeHistory(op,datas,this.getInput(selector));
				} 
				if(datas.length > 1){
					input.data("multiMatch",true)
				}else{
					input.removeData("multiMatch");
					suggestion.validStyle(input);
				} 
				//判断是否有bind之前的操作，如果操作返回不为false时,生成选择项
				if (!op.fnBeforeBinded || op.fnBeforeBinded(selector, datas, op) !== false) {
					var body = this.getSelectorBody(selector);
						body.html(op.panelBegin + Ccay.UI.tmplList(op.item, datas) + op.panelEnd);
						
						if(op.defaultSelect === false){
							suggestion.validStyle(input);
							var goal = selector.find('.' + op.itemClass + ':first');
							input.ccayGetValue() && goal.addClass(op.preSelected);
						}else {
							body.find('.' + op.itemClass + ':first').addClass(op.preSelected);
						}
						datas.length && selector.removeClass("selector-data");
						//op.defaultSelect !== false ? body.find('.' + op.itemClass + ':first').addClass(op.preSelected) : suggestion.validStyle(input);
							
						//input = this.getInput(selector);
					if(datas.length && selector.isVisiable())
					{
						this.setWidth(selector, op,input);
						// 检查selector弹出的位置并修正
						input.length && op._offset !='position' && Ccay.UI.checkPopuperPosition(input, selector);	
					}
					var val  = input.ccayGetValue();
					//当有值模式下，给多选框添加已选样式
					if(val){
						if(op.multi){
							var valArr = val.split(op.valueSplit);
							$.each(valArr, function(){
								if(this){
									body.find("li.list-item[val='"+this+"']").not(".selected").addClass("selected")
								}
							})
						}else{
							body.find("li.list-item[val='"+val+"']").not(".selected").addClass("selected  selected-pre")
						}
					}
				}
				op.fnBinded && op.fnBinded(selector, datas);
				
				op.dataset = Ccay.Format.convertArrayToObject(datas,op.valueField,true);
				op.total = datas.length;
				
				var initInput = selector.data('initInput');
				if (initInput) {
					initInput = $(initInput);
					if(op.showfirstItem && !initInput.getValue())
					{
						op.showfirstItem = null;
						this.selectedFirst(initInput,selector,op);
					}
					else
						dropdown.initInputValue(initInput,selector);
				}
				else if(datas.length == 1  && datas[0] && !datas[0]._history && op.defaultSelect !== false)
				{
					//input = dropdown.getInput(selector);
					if(input.length)
					{
						if(op.connectFill || op.showfirstItem || (op._type == "sgt" && op.showfirstItem !== false))
						{
							op.showfirstItem = null;
							this.selectedFirst(input,selector,op); 
							
							if(input.parents(".gt-grid").length && input.hasClass("ccay-user")){
								input.removeClass("error");
								input.next("label.error").hide();
							}
						}
					}
				}else if(datas.length>0 && op.showfirstItem === true){
					op.showfirstItem = null;
					this.selectedFirst(input,selector,op); 
				}
				if(input.length && input[0] != document.activeElement || !datas.length)
				{ 
					/*
					 * wx227635
					 * 采用延迟 是由于需求：在下拉框没数据的时候 延迟一秒关闭提示信息
					 * 添加判断 是处于修改BUG 部门控件再次选择的时候，会直接关闭弹出层
					*/
					if(datas.length){
						selector.data("isDel") == true ? selector.data("isDel",false) : selector.hide();
					}else {
						setTimeout(function(){
							selector.hide();
						},1000);
					}
					(op._type == "sgt") && suggestion.validStyle(input);
					if(needvalid!==false && dropdown.getSelector(input).data('op')){
						//!selector.data("notValid") && input.valid();
						//下拉框 异步查询  设置 lazyload=false  初始化加载的时候出现必填校验。
						if(op.lazyload){
							!selector.data("notValid") && input.valid();
						}
						input.hasClass("error") && selector.removeClass("selector-data");
						if(input.parents(".gt-grid").length && input.hasClass("ccay-user") && !datas.length){
							input.addClass("error");
							var errorLbl = input.next("label.error");
							if(errorLbl.length == 0){
								errorLbl = $.create("label","error").click(function() {
									$(this).hide().addClass('er-handle');
								});
							}
							errorLbl.html($i18n("ccay.jquery.validate.ccayUser")).css({top : 23, left : 0});
							input.after(errorLbl);
							errorLbl.show();
							return ;
						}
					}
				}
			}
		},
		initInputValue : function(initInputs,selector) {
			selector.removeData('initInput');
			$(initInputs).each(function() {
				var input = $(this), value = input.getValue();
				if (value){
					if(input.hasClass("grid-editor"))
						dropdown.setValue(input, value,null,null,null,true);
					else
						dropdown.setValue(input, value);
				}
					
			});
		},
		getItemText : function(item) {
			return $(item.find('.list-text').get(0)).text();
		},
		selectedFirst:function(input,selector,op){
			selector.removeData('initInput');
			var item = selector.find('.' + op.itemClass + ':eq(0)');
			dropdown.selected(op, item.attr('val'), dropdown.getItemText(item), item, selector, input);
			if(op.multi){
				selector.hide();
			}
		},
		selectedAll:function(input,selector,op,selected){
			var filter = '.' + op.itemClass + (selected ? '' : '.selected'),
				items = selector.find(filter);
			
			if(selected)
			{
				this.itemSeleted(selector,items.length > 1 ? items.addClass('selected') : items, op);
			}
			else
			{
				items.removeClass('selected');
				this.setValue(input, '', '');
			}
		},
		bindSelectorClick:function(selector,op){
			selector.delegate('.' + op.itemClass,"click",function(e){
				//dropdown.cancelClick(e);
				//if(op.displayField==='currencyCode'){
					dropdown.cancelClick1(e);
				//}
				dropdown.itemSeleted(selector,$(this),op);
			}).mousedown(function(){
				$(this).data("notValid",true);
			});
		},
		//下拉框选项允许删除 allowDel 为true时
		bindSelectorHover:function(selector,op){
			selector.delegate('.' + op.itemClass,"mouseover",function(e){
				$( this ).find(".allow-del").show();
			})
			.delegate('.' + op.itemClass,"mouseout",function(e){
				$( this ).find(".allow-del").hide();
			});
			selector.delegate('.del',"click",function(e){
				var selector = $(this).parents(".ccay-selector"),
					op = selector.data('op');
				if(op.fnBeforeRemoveItem){
					var data = op.dataset,
						parent = $(this).parents("li") ,
						val = parent.attr("val"),
						curObj = [];
					for(var item in data){
						if(item != val){
							curObj.push(data[item]);
						}
					}
					op.fnBeforeRemoveItem.call(this,data[val],op,selector);
					selector.data("isDel",true);
					dropdown.buildSelector(selector,curObj,op);
				}
				return false;
			})
		},
		itemSeleted : function(selector,item,op) { 
			var 
//			item = $(this), selector = item.parents('.ccay-selector'), 
//				op = selector.data('op'), 
				result, value, text, 
				input = dropdown.getInput(selector);

			if(op.sgtMulti && op.dedupLication){
				//如果multi为true 并且 dedupLication为true 时去重复
				var inputValue = input.dataValue().split(op.valueSplit) ,
					inputText = input.val().split(op.multiSplit),
					item_Text = dropdown.getItemText(item),
					item_Value = item.attr('val') ,
					currIndex = $.inArray(item_Value,inputValue) ,
					bool = currIndex == $.inArray(item_Text,inputText);
				
				//删除掉之前选中的，重新选中
				if(bool && currIndex != -1){
					inputValue.splice(currIndex,1);
					inputText.splice(currIndex,1);
					
					var currValue = inputValue.join(op.valueSplit),
						currText = inputText.join(op.multiSplit)+op.multiSplit , 
						currData = input.data('datas');
					currData.splice(currIndex,1);
						
					input.dataValue(currValue).val(currText).data('datas',currData);
				}
			}
			if (op.multi) {
				item.length == 1 && item.toggleClass('selected');
				var arrValue = [],arrText = [];
				
				(item.length == 1 ? selector.find('.selected'):item).each(function() {
							var selectItem = $(this);
							/*var checked= false;
							for(var i=0,len = arrValue.length;i<len;i++){
								if(arrValue[i]==selectItem.attr('val') && arrText[i]==dropdown.getItemText(selectItem) ){
									checked=true;
								}
								
							}
							if(arrValue.length==0 || !checked){  //如果选择的值已经存在 则不添加到文本
								arrValue.push(selectItem.attr('val'));
								arrText.push(dropdown.getItemText(selectItem));
							}*/
							arrValue.push(selectItem.attr('val'));
							arrText.push(dropdown.getItemText(selectItem));
						});
				text = arrText.join(op.multiSplit);
				arrText.length && (text+=op.multiSplit);
				value = arrValue.join(op.valueSplit);
			} else {
				text = dropdown.getItemText(item);
				value = item.attr('val');
			}
			if(item.hasClass("history-item")){
				//验证历史选项有效性，有效则选择，无效则删除历史选项
				dropdown.validSgtHistory(value, op, function(ret){
					if(ret){
						dropdown.selected(op, value, text, item, selector, input);
					}else{
						item.remove();
						if(selector.find(".list-item").length == 0){
							selector.hide();
						}		
						Ccay.Personalized.delInvalidHistory(op.historyKey || ( op.ajax && op.ajax.url ), value);
					}
				},input);
			}else{
				dropdown.selected(op, value, text, item, selector, input);
				//Ccay.UI.setInputFocus(input);
				Ccay.UI.setInputFocus(input, (op.multi || op.sgtMulti) ? null : 0, false) ;
			}
			
		},
		selected : function(op, value, text, item, selector, input,noClose,noConnect) {
			if (value == void 0)
				value = '';
			if (text == void 0)
				text = '';
		    //add by ckf31628 
			dropdown.getTrigger(input.removeClass("error").removeData("multiMatch").removeData("haschanged")).removeClass("warning");
			dropdown.clearInterval(op);
			
			
			dropdown.fillContainer(item, op);
			var data = op.dataset && value ? op.dataset[value] : null;
			if (!op.fnBeforeSelected || op.fnBeforeSelected.call(input, value, text, item,selector,data) !== false) {
				var oldValue = input.dataValue();
				input.dataValue(value).val(text);
				input.data('curText', value != null && text.length ? text.trim() : "");
				
				if (!op.multi && !noClose)
					selector.hide();

				if(op.multi)
				{
					selector.find('.ccay-selector-empty:first').toggleClass('ddl-selectAll',value !== "" && value.split(op.valueSplit).length == op.total)
				}
				dropdown.addTip(input,text);
				if(text && !input.data("lazyload"))
				{
					input.valid();
				}
				if (!op.fnSelected || op.fnSelected.call(input, value, text, oldValue, item,selector,data, noConnect) !== false)
				{
					if(dropdown.checkHistorySupport(op)){
						if(op.multi){
							var v =value.split(op.valueSplit);
							for ( var i = 0; i < v.length; i++) {
								Ccay.History.save(op.historyKey || ( op.ajax && op.ajax.url ),v[i], op._type =="sgt" ? data : null);
							}
						}else{
							Ccay.History.save(op.historyKey || ( op.ajax && op.ajax.url ),value, op._type =="sgt" ? data : null);
						}
					}
					if (oldValue != value) {
						if (op.fnChanged)
							op.fnChanged.call(input, value, text,oldValue, item,selector,data);
						else if (input.length && input[0].onchange)
							input[0].onchange();
					} 
				}
				else return false;
			}
			else
				return false;
		},
		addTip:function(input,text){
			if(input.length && input[0].tagName == "INPUT"){
				if(text.length > 20)
					input.attr('title',text);
				else
					input.removeAttr('title',text);
			}
		},
		foramtParam : function(ajax,param,field){
			var op = $.extend({},ajax);
			op.url = ajax.url.formatURI(param);
			if(ajax.data)
				op.data = ajax.data.formatURI(param);
			else if(field)
			{
				op.data = {};
				op.data[field] = param;
			}
			return op;
		},
		
		sort : function(data,sortType,field,isI18n){
			if(isI18n){
				$.each(data,function(){
					this[field] = $i18n(this[field]);
				})
			}
			return Ccay.DataHelper.sort(field, sortType!=="desc" ? "asc" : "desc", data)
		},
		sendRequest : function(selector, ajaxSetting, input, needValid) {		
			var ajax = $.extend(true,{},ajaxSetting);
			selector.removeData('lazyload');
			dropdown.clearSelector(selector);
			//开始期间
			var startTime = new Date();
			//修复开启弱验证时 人员控件td快速切换信息覆盖
			var tempCell = input.data("caller");
			Ccay.UI.ajax.setFnSuccess(ajax,function(result) {
				if(tempCell && input.data("caller") && input.data("caller")[0]!=tempCell[0]){
					return;
				}
				var data = result ? (result.result || result) : [];
				var op = selector.data("op");
				if(op.sort && data && data.length){
					data = dropdown.sort(data,op.sort,op.displayField || "text",op.i18n)
				}
				dropdown.buildSelector(selector, data,null, needValid);
				ajax.fnSuccess && ajax.fnSuccess(selector, result);
				//Ccay.Core.log(input.data('_delayValid'));
				//结束时间
				var endTime = new Date();
			},true);
			var fnError = ajax.error;
			ajax.error = function(textStatus, errorThrown,responseText, status){
				if(status == "403" && responseText.indexOf("ccay.security.00010002") > -1){
					input.removeData('called').removeData('cached').removeData("calledText");
					selector.hide();
					Ccay.Component.Session.openRebuildDialog(function(){
						dropdown.sendRequest(selector, ajaxSetting, input)
					});
					return;
				}
				selector.data('isDefault',0);
				input.removeData("_matching").removeData("haschanged").removeData("called").valid();
			//	selector.data('lazyload',true);
				if(fnError)
					return fnError();
			};
//			ajax.success = function(result) {
//				var data = result ? (result.result || result) : result; 
//				dropdown.buildSelector(selector, data);
//				ajax.fnSuccess && ajax.fnSuccess(selector, result);
//			};
			var returnObj;
			if (ajax.beforeRequest) {// 执行请求之前的事件
				returnObj = ajax.beforeRequest(ajax, input, selector);
				if ($.isPlainObject(returnObj) && !$.isEmptyObject(returnObj))
					return dropdown.ajax(returnObj,input);
				else if (returnObj === false)
				{
					//修复异步方法的时点击下拉就会出现必填校验并且在disabled的情况下
					input.removeData('called').removeData("_matching");
					if(!$(input).attr("disabled")){
						!selector.data("notValid",false) &&input.valid();
						selector.removeData("notValid");
					}
					return;
				}else if(returnObj.length){//Liujian wx200947 add 
					$.each(returnObj,function(i,j){
						dropdown.ajax(returnObj[i],input);
					});
					return ;
				}
					
			}
			this.clearInterval(selector.data("op"));
			dropdown.ajax(ajax,input);
		},
		ajax:function(ajax,input){
			//判断是否有阻止request的行为
//			if(input.data('cancelRequest'))
//			{
//				input.removeData("_matching")
//				return;
//			}
			if(input.data('ddl_locked'))
			{
				input.data('calledText', null).removeData("called");
				return;
			}
			input.data("called",1);
			var trigger = input.next('.ccay-dropdown-btn');
			if(input.next("label.error").length){
				trigger = input.next().next('.ccay-dropdown-btn');
			}
			if(ajax.loading == void 0)
				ajax.loading = 'ui';
			Ccay.UI.ajax(ajax,trigger.length ? trigger : input.parent());
		},
		clearInterval:function(op){
			if(op.interval)
			{
				clearInterval(op.interval);
				op.interval = null;
			}
		},
		callSelector : function(e) {
			dropdown.cancelClick(e);
			var input = dropdown.getInput(this);

//			$('.ccay-selector:visible').hide();

			var selector = dropdown.getSelector(input), op = selector.data('op'), isInit;
			
			if (op.connector)
				isInit = dropdown.connectDdl(input, selector, op);
			else if (selector.data('lazyload')) {
				dropdown.sendRequest(selector, op.ajax, input);
				isInit = false;
			}

			if (isInit !== false) {
				var value = input.dataValue(), items = selector.find('.' + op.itemClass);
				items.filter('.selected').removeClass('selected');
				items.filter('.' + op.preSelected).removeClass(op.preSelected);
				items.first().addClass(op.preSelected);
				//清除copy模式预匹配样式
				if(op._copy)
				{
					items.filter('.pre').removeClass('pre');
					delete op._copy;
				}
				
				if (op.combo)
					items.filter('.hide').removeClass('hide');

				if (value) {
					if (op.multi) {
						Ccay.UI.matchText(value, items,
								function(result, item) {
									if (result)
										item.addClass('selected');
								}, op.valueSplit, 'val');
					} else
						selector.find('.' + op.itemClass + '[val="' + value + '"]').addClass('selected').addClass(op.preSelected);
				}
				if(items.length == 1 && input.data("connectFill")){
					dropdown.selectedFirst(input,selector,op); 
					return;
				}
			}
		
			dropdown.popup(input, selector, op);
			
		},
		popup : function(input, selector, op, isTriggerEvent) {
			if(input.hasClass("ccay-user")) {
				selector.addClass("selector-data");
			}
			if(op.defaultSelect === false){
				var goal = selector.find('.' + op.itemClass + ':first');
				goal.removeClass(op.preSelected)
				//input.ccayGetValue() ? goal.addClass(op.preSelected) : goal.removeClass(op.preSelected);
			}
			if(input.attr('ddl_locked'))
			{
				selector.hide();
				return;
			}
			// input可见时才pop，否则关闭
			if(input.isVisiable() && (document.activeElement == input[0]  || isTriggerEvent || op._type !="sgt")){
				op.onlyone && selector.data('input', input);
				//debugger;
				var position = {};
				$.extend(position, op.css);
				position.top = (position.top || 0) + input.outerHeight();
				selector.show();
				this.setWidth(selector, op,input); 
				//debugger;
				Ccay.UI.popup(input, selector, position,null,op._offset,null,true);
				this.setWidth(selector, op,input);
				(document.activeElement !== input[0]) && !$(document.activeElement).hasClass("ccay-dropdown") && input.focus();
			}else{
				selector.isVisiable() && Ccay.UI.popupClose(selector);
			}	
			if(input.hasClass("ccay-user")) {
				!selector.find('.' + op.itemClass+ ':visible:first').length ? selector.addClass("selector-data") : selector.removeClass("selector-data");
			}
		},
		setTrigger : function(input, fnCall,clickTrigger,op) {
			var trigger = $.create('a').addClass('ccay-dropdown-btn').attr("style","margin-right:0px;").insertAfter(input);
			if(op.showTrigger!==false){
				if(op.readOnly===true){
					input.unbind("click.trigger").bind("click.trigger",function(){
						trigger.click();
					});
				}
				//点击文本框弹出下拉数据
				if(op.dataPopup===true){
					input.unbind("click.trigger").bind("click.trigger",function(){
						trigger.click();
					});
				}
				
				trigger.click(function(e){
				    //如果触发器有warning样式，说明查询出来多条记录，提示用户选择，通过focus触发事件，popup出匹配的记录
				   	if(trigger.hasClass("warning")){
				   		input.focus();
				   		return;
				   	}
					var selector = dropdown.getSelector(input).data("isDefault",0);;
					if(selector.data("isColse")){
						selector.data("isColse",null);
						return
					}
					if(selector.isVisiable())
						selector.hide();
					else{
						fnCall.call(input,e);
					}
					
					(document.activeElement !== input[0]) && input.focus();
				}).mousedown(function(e){
					var selector = dropdown.getSelector(input).data("isDefault",0);
					selector.data("notValid",true);
					if(selector.isVisiable()){
						selector.data("isColse",true);
					}
				});
				input.addClass('dropdown-trigger');
				input.is('textarea') && trigger.addClass('dropdown-areabtn');
				clickTrigger && input.bind("click",function(e){
					fnCall.call(this,e);
				})
			}else{
				//ldap控件模式下，生成trigger后隐藏掉。当存在warning样式才显示
				//ldap控件模式下，如果支持显示历史选项，则将trigger渲染成历史选项样式
				if(dropdown.checkHistorySupport(op)){
					trigger.addClass("history hide").attr("title",$.i18n.prop("ccay.dropdown.ldap.historyrecord")).click(function(e){
						var target = $(this);
						if(target.hasClass("warning")){
							input.focus()
						}else{
							var selector = dropdown.getSelector(input), op = selector.data('op');
							dropdown.clearSelector(selector);
							var history =dropdown.mergeHistory(op,[],input,true);
							if(history.length > 0 ){
								input.focus();
								dropdown.buildSelector(selector,history , op);
								dropdown.popup(input, selector, op);
							}
						}
					});
				}else{
					//添加在Igrid中人员控件历史记录没有title提示。 
					 trigger.addClass("hide").attr("title",$.i18n.prop("ccay.dropdown.ldap.historyrecord")).click(function(e){
						input.focus()
					});
				}
			}
		},
		getTrigger : function(input) {
			var tg = input.next('.ccay-dropdown-btn');
			return  tg.length >0 ? tg : input.next().next(".ccay-dropdown-btn")
		},
		fillContainer : function(item, op) {
			if (item && !op.multi && op.fillContainer) {
				var data = item.attr('fill');
				if (data)
					data = jQuery.parseJSON(data);
				
				$(op.fillContainer).jsonData(data || {});
			}
		},
		validInput : function(input) {	
			var result = true,text = input.validVal().trim();
			if (text.length)
				result = input.data('curText') == text;
			else
				input.removeData('curText');
			
			if(!result)
			{
				//当验证失败时，判断是否关闭了输入验证
				var op = dropdown.getSelector(input).data('op');
				if(op.valid === false)
				{
					//关闭验证下的combobox，设置输入值
					input.removeData('curText');
					this.setValue(input, text, text);
					return true;
				}
			}
			return result;
		},
		matchInput : function(e) {
			var input = $(this);
			if(input.data('copy'))
			{
				input.removeData('copy');
				return;
			}
			var text = input.val(),selector = dropdown.getSelector(input), op = selector.data('op'),isMatch = true;

			if(op.multi && e.keyCode==13){
				return;
			}
			
			if (selector.data('lazyload') || op.connector) {
				var ajax = $.extend({},op.ajax);
				if(ajax.fnSuccess){
					var fnSuccess = ajax.fnSuccess;
					ajax.fnSuccess = function(result){
						op.connector && input.val(text);
						dropdown.matchInput.call(input,e);
						fnSuccess(result);
					}
				}
				else
					ajax.fnSuccess = function(result){
						op.connector && input.val(text);
						dropdown.matchInput.call(input,e);
					}
				
				//处理联动之后的联想数据
				if(op.connector){
					if(dropdown.connectDdl(input, selector, op,ajax) !== false)
						isMatch = true;
				}
				else
				{
					dropdown.sendRequest(selector, ajax, input);		
					isMatch = null;
				}		
			}
			
			if(isMatch)
			{
				if (selector.length) {
					var items = selector.find('.'+ op.itemClass);
					if(items.length){
						var hideNum = 0,firstItem;
						if (text) {
							if(op.multiDisabled && op.multi){
								var myCurValues = input.dataValue(),myCurTexts = text.split(op.multiSplit);
								text = myCurTexts[myCurTexts.length-1];
								myCurTexts.splice(myCurTexts.length-1,1);
								if(myCurTexts.length){
									var checkValues=[],checkText = [op.multiSplit,myCurTexts.join(op.multiSplit),op.multiSplit].join("");
									items.each(function(i,item){
										if(op.multi){
											if(checkText.indexOf(op.multiSplit+op.dataset[$(this).attr("val")][op.displayField]+op.multiSplit)!=-1){
												$(this).addClass("selected");
												checkValues.push($(this).attr("val"));
											}else{
												$(this).removeClass("selected");
											}
										}
									});
									input.dataValue(checkValues.join(op.valueSplit)).data("curText",input.val().trim());
								}
								if(!text){
									return;
								}
							}
							op.cacheReqest!==false && Ccay.UI.matchText(text.trim(), items, 
									function(result, item) {
										if(result)
										{
											hideNum == 0 && (firstItem = item);
											hideNum++;
										}
										item.toggleClass('hide', !result).removeClass(op.preSelected);
									});
						} else
						{
							items.removeClass("selected");
							selector.find('.' + op.itemClass + '.hide').removeClass('hide').removeClass(op.preSelected);
							dropdown.selected(op, '', '', null, selector, input,1)
						}
						if(op.multiDisabled && op.multi && input.dataValue() && firstItem && $.inArray(firstItem.attr("val"),input.dataValue().split(op.valueSplit))!=-1){
							input.data("curText",(myCurTexts.join(op.multiSplit)+op.multiSplit).trim());
							return;
						}
						// 丰富选择的模式下只有一项时不自动选择
						if(hideNum == 1 && !("richMode" in op) && op.showfirstItem !== false && op.defaultSelect !== false){
							dropdown.itemSeleted(selector, firstItem, op);
						}else{
							items.eq(0).addClass(op.preSelected);
							!items.filter(":visible").length && input.valid();
							if (selector.css('display') == 'none') {
								if (op.onlyone)
									selector.data('input', input);
								//dropdown.popup(input, selector, op);
							};
							//过滤之后重设宽度和位置
							dropdown.popup(input, selector, op);
						}
					}
				}

			}
		},
		setConnector : function(callers, connector) {
			
			if(typeof(connector) == 'string'){
				dropdown.setConEvent($(connector),callers);
			}
			else if (connector.length) {
				$.each(connector,function(i,op){
					dropdown.setConEvent($(op.target),callers);
				})
			}
		},
		setConEvent:function(con,callers){
			if(con.hasClass('ccay-dropdown'))
			{
				var selector = dropdown.getSelector(con), 
				op = selector.data('op'), fnSelected = op.fnSelected;
				op.fnSelected = function(value, text, oldValue, item,selector,data, noConnect) {
					!noConnect && dropdown.validConnectValue(callers, value);
					if(fnSelected)
						fnSelected.call(this,value, text, oldValue, item,selector , data);
				};
			}
		},
		setConnetctAjax:function(op){
			var setAjax = op.ajax.setAjax;
			op.ajax.setAjax = function(ajax,input){
				var conValue = op.fnGetConnectValue ? op.fnGetConnectValue(input,op) : dropdown.getConnectValues(op.connector);
				if(conValue){
					ajax.url = op._type == 'sgt' ? ajax.url.formatField({connect:conValue}) : ajax.url.format(conValue);
					if(setAjax)
						return setAjax(ajax,input);
				}
				else
					return false;
			}
		},
		getConnectValues:function(connector){
			if(typeof(connector) == 'string')
				return ($(connector).dataValue()+"").encodeURI(); 
			else{
				var conValue = [];
				$.each(connector,function(i,op){
					var con = $(op.target),value = con.hasClass("ccay-dropdown") ? con.dataValue() : con.val() || con.text();
					if(value.length == 0)
					{
						if(op.defaultValue == null){
							conValue = null;
							return false;
						}
						else
							value = op.defaultValue;
					}
					if(value != null)
						conValue.push(op.paramName + '=' + (value+"").encodeURI());
				})
				return conValue ? conValue.join('&') : null;
			}
		},
		connectDdl : function(input, selector, op,ajax) {
			var conValue = op.fnGetConnectValue ? op.fnGetConnectValue(input,op) : dropdown.getConnectValues(op.connector);
			if (input.data('conVal') != conValue || op.cache === false) { 
				input.data('conVal', conValue);
				if(ajax == null)
					ajax = op.ajax;
				
				if (ajax) {
					if (conValue && conValue.length) {
						if(input.getValue())
							selector.data('initInput',input);
						dropdown.sendRequest(selector, ajax, input);					
						return false;
					} 
					else // 为空值的时候不重现绑定，清理内容
						dropdown.clearSelector(selector);
					
				} else {
					if (conValue)
						Ccay.UI.matchText(conValue, selector.find('.'+ op.itemClass),
								function(result, item) {
									item.toggleClass('list-hide', !result);
								}, op.valueSplit, 'val');
					else
						selector.find('.list-hide').removeClass('list-hide');
				}
			}
		},
		validConnectValue : function(callers, checkValue) {
			$(callers).each(function(i) {
				var input = $(this),selector = dropdown.getSelector(input), 
				op = selector.data('op'),oldValue = input.data('conVal');
				if(!op){
					return;
				}
				//为联想框时，去掉上次请求的信息
				if(op._type == 'sgt')
				{
					input.removeData('calledText');
					selector.removeData('isDefault');
				}
				if (oldValue != void 0 && oldValue !== "") {
					var conValue = op.fnGetConnectValue ? op.fnGetConnectValue(input,op) : dropdown.getConnectValues(op.connector);
					if (oldValue != conValue || op.cache === false) {
						if(op._type == 'sgt')
							input.data('conVal', conValue);
							
						var value = input.dataValue(),
							item = selector.find('[val="' + value+ '"].'+ op.itemClass + ":visible"); 

						if (value) {
							var matchText = dropdown.getItemText(item);
							if (matchText.toLowerCase() != input.val().toLowerCase())
								dropdown.selected(op, '', '', item, selector,input);
						} else
							dropdown.selected(op, '', '', null, selector,input);
					}
				} 
				else if(!selector.data('lazyload') && op._type != 'sgt') {					
					dropdown.connectDdl(input, selector, op);
				}
				else if(input.val().length){
					dropdown.selected(op, '', '', null, selector,input);
				}
				//是否自动展开级联子记录
				if(op.connectFill && checkValue){
					if(dropdown.currConTimeout){
						window.clearTimeout(dropdown.currConTimeout);
						dropdown.currConTimeout = false;
					}else{
						dropdown.currConTimeout = setTimeout(function(){
							if(input.is(":visible")){
								input.data("connectFill",true);
								dropdown.getTrigger(input).click();
								input.data("connectFill",false);
								dropdown.currConTimeout = false;
								//用来callSelector的时候，如果该参数为true，并且过滤后只有一项的情况下，自动填充

							}
						},100);
					}
				}
				
			});
		}, 
		setValue : function(input, value, text,checkLoad,valid, noconnect) {
			
			var selector = dropdown.getSelector(input), op = selector.data('op'), item,isRequest;
			if (!text && value != null && value !== '') {
				value += '';
				if (!op.richMode) {
					if (selector.data('lazyload') || (checkLoad && op.connector && op.lazyload == false)) {
						if(op.connector == null || (checkLoad && op.lazyload == false)){
							selector.data('initInput', input);
							input.dataValue(value);
							isRequest = true;
							dropdown.sendRequest(selector, op.ajax, input);
						}
						else
							selector.removeData('lazyload');
					} 
					else {
						if (op.multi) {
							text = [];
							Ccay.UI.matchText(value, selector.find('.'+ op.itemClass), 
									function(result,item) {
										if (result)
											text.push(dropdown.getItemText(item));
									}, op.valueSplit, 'val');

							text = text.join(op.multiSplit);
						} else {
							item = selector.find('.' + op.itemClass + '[val="' + value + '"]');
							if (item.length)
								text = dropdown.getItemText(item);
						}
						if(!text && op.valid === false)
							text = value;
					}
				}
			}
			if(!isRequest)
				dropdown.selected(op, value, text, item, selector, input,true,noconnect);
			return input;
		},
		reBind : function(input, ajax, datas) {
			var selector = dropdown.getSelector(input), op = selector.data('op'), 
				value = input.dataValue();
			
			/*
				lwx200947 如果是丰富组件，讲 setp 标识设为1，让其下次点击的时候再次重新初始化。
				修复丰富组件 reBind 之后变成普通下拉框的问题
				丰富组件reBind 必须使用 ajax 重新绑定数据
			*/
			if(op.richMode){
				selector.data('step',1);
				op.richMode.op.url= ajax.url;
			} 
			
			if (datas) {
				dropdown.clearSelector(selector);
				dropdown.buildSelector(selector, datas, op, false);
				if (value)
					dropdown.setValue(input, value);
			} else {
				var setting = {};
				$.extend(setting, op.ajax, ajax);
				var curValue = value || input.val();
				input.val(curValue);
				if (Ccay.DataHelper.isEmpty(curValue) ) 
					dropdown.sendRequest(selector, setting, input, false);
				else
					dropdown.setValue(input, curValue);
			}
		},
		disabled : function(input, enable, op) {
			if (!op)
				op = $(input.data('selector')).data('op');

			if (enable) {
				op.fnGetTrigger(input).show();
				input.removeAttr('disabled');
			} else {
				op.fnGetTrigger(input).hide();
				input.attr('disabled', 'disabled');
			}
		},
		readonly : function(input, enable, op) {
			if (!op)
				op = $(input.data('selector')).data('op');

			if (enable) {
				op.fnGetTrigger(input).show();
				input.removeAttr('readonly');
			} else {
				op.fnGetTrigger(input).hide();
				input.attr('readonly', 'readonly');
			}
		},
		//点击文本框弹出下拉数据
		dataPopup : function(input, enable, op) {
			if (!op)
				op = $(input.data('selector')).data('op');

			if (enable) {
				op.fnGetTrigger(input).show();
				input.removeAttr('dataPopup');
			} 
		  },
		
		
		checkEmpty : function(e) { 
			var input = $(this);
			if (Ccay.DataHelper.isEmpty(input.val()) && !Ccay.DataHelper.isEmpty(input.dataValue())) {
				var selector = dropdown.getSelector(input);
				dropdown.selected(selector.data('op'), '', '', null, selector, input,true);
			}
		},
		//复制粘贴事件
		onPaste:function(e){
			var input = $(this),oldValue = input.val(),selector = dropdown.getSelector(input),
				op=selector.data("op");
				//复制事件清除延迟加载和初始化赋值设置
				input.removeData("initInput");
				
				setTimeout(function(){
					var matchText = input.val();
					if(matchText && matchText.trim())
					{
						if(op.multi)
						{
							if(selector.data("lazyload")){
								var ajax = $.extend(true,{},op.ajax);
								Ccay.UI.ajax.setFnSuccess(ajax,function(){
									dropdown.matchPaste(input,selector,op,oldValue,matchText);
								});
								dropdown.sendRequest(selector, ajax, input);
							}
							else{
								dropdown.matchPaste(input, selector, op,oldValue,matchText);
							}
						}
						else
						{
							dropdown.matchInput.call(input,e, true);
							if(op._type == "sgt"){
								input.data('copy',1);
							}
						}
							
					}
				},10);
				
		},
		//匹配事件
		matchPaste:function(input,selector,op,oldValue,matchText){
			dropdown.selectedAll(input, selector, op,false);
			matchText = matchText.split(op.multiSplit.trim());
			
			var items = selector.find('.' + op.itemClass);
			for(var i =0,len = matchText.length;i<len;i++)
			{
				var text = matchText[i].trim(),firstMatch,matchNum = 0;
				if(text)
				{
					Ccay.UI.matchText(text, items,function(result, item,matchText) {
						if(result){
							if(matchNum > 0)
							{
								item.addClass('pre');
							}
							else
								firstMatch = item;
							matchNum++;
						}
					});
					if(matchNum)
					{
						if(matchNum == 1)
						{
							dropdown.itemSeleted(selector, firstMatch, op);
							items = items.filter(':not(.selected)');
						}
						else
							firstMatch.addClass('pre');
					}
				}
			}
			op._copy = true;
			this.popup(input, selector, op);
		}
	}

	
	$.fn.dropdown = function(ops, datas) {
		var op = $.extend(true, {
			appendAfter:Ccay.UI.Config.dropdown.appendAfter,
			container:null,		//添加下拉菜单的容器
			_type:null,
			multi : false, 				// 是否允许多选
			onlyone : true, 			// 是否使用唯一模式，既只会生成一个selector
			combo : true, 				// combo模式
			delay : Ccay.UI.Config.dropdown.comboDelay, 				// combo过滤延迟时间
			emptyText : null, 			// 空选显示文本，默认不显示空项;
			ajax : null, 				// ajax设置如：ajax:{url: null, data:null,beforeRequest:null, fnsuccess:null,fnerror:null}
			lazyload : true, // 下拉选择时，是否延迟加载（当选择控件有初始值时，则延迟加载无效）
			initInput : true, // 延迟加载时是否根据初始值，进行请求并选择
			cssname : null, // 自定义样式名
			panelBegin : "<ul class='list'>",
			item : '<li class="{0} ${&data._history}" val="${&{1}}" {3}  ><span class="list-text">${{2}}</span></li>',
			panelEnd : "</ul>",
			itemClass : 'list-item',
			preSelected : 'selected-pre',
			scrollBody:'.ccay-selector-body',
			css : {top : -1},
			valueField : "value",
			displayField : "text",
			showfirstItem: null,
			fillField : null,
			fillContainer : null,
			minWidth : 30,
			maxWidth : 800,
			multiSplit : Ccay.Config.Format.textSplit,
			valueSplit : Ccay.Config.Format.valueSplit,
			connector : null,
			pasteMatch : true, //是否开启多选复制粘贴匹配
			fnBinded : null, // 绑定选择列表的方法，fnSelected(value, text, item,selector，input);
			fnBeforeBinded : null, // 绑定之前的事件，fnBeforeBinded(selector,datas,op)，返回false则不回执行内置的绑定方法
			fnSelected : null, // 选择项的方法，fnSelected(value, text,oldValue, item,selector);this为input
			fnBeforeSelected : null, // 选择之前的事件，fnBeforeSelected(value, text, item,selector)，返回false则不回执行内置的方法和fnSelected，this为input
			fnChanged : null, // 选择之前的事件，fnChanged()，this为input,同时支持onchange事件
			fnSetTrigger : null, // 设置填出选择触发器的方法,触发对象必须与input在同级
			fnGetTrigger : dropdown.getTrigger,
			fnCallSelector : dropdown.callSelector,
			fnMatchInput : dropdown.matchInput,
			fnKeyEnter : null,
			fnBuildSelector:null,
			fnInitComplete:null,//初始化完成之后事件
			addEmptyOption : Ccay.UI.Config.dropdown.addEmptyOption 
				// , richMode:{
				// mode:'grid',
				// op:{},
				// url:''
				// }
		}, ops);
		if(op.allowDel === true){
			op.item = '<li class="{0} ${&data._history}" val="${&{1}}" {3}  ><span style="float:left;" class="list-text">${{2}}</span><span style="float:right;display:none;" class="allow-del"><a class="ccay-icon del"></a></span></li>'
		}
		//扩展兼容dataset数据属性
		datas || op.dataset && (datas = op.dataset);
		
		//如果用户设置了addEmptyOption,浏览器支持placeholder特性的时候，则使用placeHolder，否则模拟
		if(op.addEmptyOption){
			if(canPlaceholder){
				this.attr("placeholder", op.addEmptyOption)
			}else{
				this.data("addEmptyOption", op.addEmptyOption);
				!this.val() && this.val(op.addEmptyOption).dataValue("");
				
			
			}
		}
		
		//op.appendAfter = false;
		if (datas || op.ajax || op.richMode) {
			op.item = op.item.formatText(op.multi ? op.itemClass+ " list-mulit" : op.overflow?op.itemClass+ " overflow":op.itemClass, op.valueField,
					op.displayField, (op.fillField ? " fill='${#"+ op.fillField + "}'" : ""));
			
//			if (op.multi && op.combo)// 多选方式不支持combo模式
//				op.combo = false;

			var selector = $.create('div','ccay-selector').attr('tabindex',-1), selectorid, 
				firstItem = this.first(), lazyload;
			if (op.cssname)
				selector.addClass(op.cssname);

			selectorid = dropdown.setSelector(firstItem, selector, op);
			richSelector.init(selector, op);
			var value = this.validVal();
			if (datas) {//固定数据源
				dropdown.buildSelector(selector, datas, op);
			} else if (op.ajax) {
				if(op.showfirstItem && value.length == 0)
				{//是否自动选择第一项
					op.lazyload = false;
					selector.data('initInput', this.selector || this);
				}
				else if(op.initInput && value.length)//是否处理回写
					selector.data('initInput', this.selector || this);
				
				if(op.connector)//设置联动ajax
					dropdown.setConnetctAjax(op);

				if (op.ajax.success)
					Ccay.UI.ajax.setFnSuccess(op.ajax);		
				
				if (op.lazyload) {//延迟加载
					var value = this.validVal();
					if (op.initInput && value.length) {//初始化数据回写
						lazyload = false;
					} else {
						selector.data('lazyload', true);
						lazyload = true;
					}
				}
				lazyload || dropdown.sendRequest(selector, op.ajax, firstItem);
			}
			//初始化联动
			op.connector && dropdown.setConnector(this,op.connector);

			return this.each(function(i) {
				var input = $(this).addClass('ccay-dropdown').attr("autocomplete","off").managerReg('dropdown',true), 
					value = input.validVal();
				//设置触发器
				op.fnSetTrigger ? op.fnSetTrigger(input,op.fnCallSelector,op.clickTrigger,op) : dropdown.setTrigger(input, op.fnCallSelector,op.clickTrigger,op);
				if (op.combo) {//combo设置
					input.bind('keydown',function(e){
						if(e.ctrlKey && e.keyCode == 86)
						{
							input.removeData('copy');
							return;
						}
						if(op.multiDisabled && op.multi){
							return;
						}
						if(op.multi && Ccay.UI.isKeyDownValue(e))
						{
							e.stopImmediatePropagation();
							return false;
						}
					})
					if(op.multiDisabled && op.multi){
						dropdown.setCombobox(input, op);
						input.prop('readonly') && dropdown.disabled(input, 0, op);
					}
					if(!op.multi)
					{
						dropdown.setCombobox(input, op);
						input.prop('readonly') && dropdown.disabled(input, 0, op);
					}
				}
				else
					input.prop('readonly', 'readonly');

				if (!op.onlyone && i > 0) {//复制selector
					selector = selector.clone(true);
					selectorid = dropdown.setSelector(input, selector, op);
				}

				input.data('selector', selectorid);
				//if(!op.isMulti)
				//注册键盘事件、失去焦点的非空检查
				input.keydown(dropdown.keydown).blur(dropdown.checkEmpty);
				//注册复制粘贴事件
				op.pasteMatch && op.combo && input.bind("paste",dropdown.onPaste)

				if (value.length && !input.dataValue()) {	
					input.dataValue(value);
					if (input.data('setValue') != 0) {//非特定设置值模式
						if (lazyload == null)//非ajax模式设置值
						{
							dropdown.setValue(input, value);
						}
						else {
							if (!op.initInput)//非自动回写模式下，第一次点击时回写
								input.one("click", function(e) {
										var input = $(this), selector = dropdown.getSelector(input), op = selector.data("op");
										selector.data('initInput', input);
										op.fnCallSelector.call(input, e);
									});
						}
					}
				}
				input.click(dropdown.cancelClick);
				(op.richMode && op.richMode.mode == 'dialog') || Ccay.UI.bindPopupClose(input,selector);
				typeof op.fnInitComplete == "function" && op.fnInitComplete.call(input,input);
				op.readOnly === true && input.attr("readonly","readonly");
			});
		}
		return this;
	}
	// 注册manager
	Ccay.UI.regManager('dropdown', {
		setValue : function(value, text) {
			return dropdown.setValue(this.ctr, value, text,true);
		},
		reBind : function(ajax, datas, defalutValue) {
			return dropdown.reBind(this.ctr, ajax, datas, defalutValue);
		},
		getSelector:function(){
			return dropdown.getSelector(this.ctr);
		},
		disabled : function(enabled) {
			return dropdown.disabled(this.ctr, enabled);
		},
		lock:function(input,locked){
			input.data("ddl_locked",locked); 
		},
		valid : function() {
			return dropdown.validInput(this.ctr);
		},
		resetLazyLoad:function(){
			this.ctr.data('lazyload',1);
		},
		hide:function(visiable){
			var operate = visiable ? "show" : "hide";
			this.ctr[operate]();
			visiable || Ccay.UI.popupClose(dropdown.getSelector(this.ctr));
			dropdown.getTrigger(this.ctr)[operate]();
		},
		readonly:function(enabled){
			return dropdown.readonly(this.ctr, enabled);
		}
		//取消请求操作
//		cancelRequest:function(enable){
//			this.ctr.data("cancelRequest",enable !== false ? true : null);
//		}
	});
	$.validator.addMethod("ccay-combobox", function(value, element) {
			return dropdown.validInput($(element));
	});

	var suggestion = {
		//设施触发器
		setTrigger : function(input, fnCall,clickTrigger,op) {
			//Ccay.UI.delayEvent(input, 'keyup', suggestion.callSelector, input.data('delay'), Ccay.UI.isKeyDownValue);
			var running,time,triggerTime = input.data('delay') / 1000;
			triggerTime = triggerTime > 1 ? triggerTime-1 : 1;
			//绑定键盘键入的延迟联想方法
			//input.removeData('delay').bind('keyup',function(e){
			input.removeData('delay');
			Ccay.UI.delayEvent2(input,'keyup', function(e){
				if(e.keyCode === 13){
					$(this).data("round",0);
					return false;
				}
				
				var input = $(this),selector = dropdown.getSelector(input),op = selector.data("op");
				if(!input.val()){
					suggestion.validStyle(input);
				}
				
				if(input.hasClass("placeholder")){
					input.attr("search",input.val());
				}
				
				//input.removeData("haschanged");
				if(e.ctrlKey && e.keyCode == 86){
					input.removeData('calledText');
					suggestion.callSelector.call(input); 
				}	
				else if(Ccay.UI.isKeyDownValue(e)){
					time = 0;
					if(!op.interval)
					{
						//Ccay.Core.log('nocall');
						//判断是否是不请求状态
						if(input.data("nocall")){
							input.removeData("nocall");
						}
						else{	
							//设置匹配中状态
							e.keyCode !== 13 && input.data("_matching",true);			
							op.interval = setInterval(function(){
								if(input.data('called')){
									//Ccay.Core.log('delayEvent2:called is true clearInterval！');
									dropdown.clearInterval(op);
									time = 0;
									//清除状态
									input.removeData("_matching");
									
								}
								else if(time == triggerTime || time > triggerTime){
									//Ccay.Core.log('delayEvent2:matchKeydown');
									 
									suggestion.matchKeydown(input, selector, op);
									op.interval = null;
									
									op.defaultSelect === false && suggestion.validStyle(input);
									time = 0;
								}
								else
									time++;
							},200);

						}
						
					}
				}
			},op.delay);
		}, 
		matchKeydown:function(input,selector,op){
			op.interval && clearInterval(op.interval);
			var text = op.sgtMulti ? suggestion.getCurrentText(input, op.multiSplit,op.valueSplit).text : input.val();
			if(suggestion.checkSuggestText(input,selector,op,text) && op.onlyOneRequest !== false)
			{
				input.removeData("_matching");
				op.interval && clearInterval(op.interval);
				if(suggestion.filter(text,selector,op,input)){
					dropdown.popup(input, selector, op);
				}
				return;
			}
			suggestion.callSelector.call(input,true);

		},
		//缓存焦点位置
		cacheFocus : function(input,pos) {
			input.data('pos', pos || Ccay.UI.getInputFocus(input));
			//Ccay.Core.log(["cache:",input.data('pos')]);
		},
		//数据绑定之后信息处理事件
		selectedBinded:function(selector, datas){
			var op = selector.data('op');
			selector.data('total',datas.length);
			if(datas.length == op.suggestNum || datas.length == 0)
				this.showMessage(selector,datas.length > 0 ? "overNum" : "noMatch",op)
			else
				this.showMessage(selector);
			var suggestInputValue = dropdown.getInput(selector);
			//是否设置多选联想复选框
			if(op.suggestMulti){
				var curData = suggestInputValue.ccayGetValue();
				curData = curData.split(",");
				var suggestTrs = selector.find(".ccay-suggest-body tr");
				selector.find(".ccay-suggest-head .suggestSelectAll").unbind("click").bind("click",function(){
					
					if($(this).parent("tr").hasClass("suggest-selectAll")){
						$(this).parent("tr").removeClass("suggest-selectAll");
						suggestTrs.find("td:first").click();
					}else{
						$(this).parent("tr").addClass("suggest-selectAll");
						for (var y = 0; y < suggestTrs.length; y++) {
							if($(suggestTrs[y]).find("td:first").hasClass("suggest-multi-noSelect")){
								$(suggestTrs[y]).find("td:first").click();
							}
						}
					}
				});
					suggestTrs.find("td:first").addClass("suggestSelect").addClass("suggest-multi-noSelect");
					$.each(curData,function(i,d){
						for (var y = 0; y < suggestTrs.length; y++) {
							if(d == $(suggestTrs[y]).attr("val")){
								$(suggestTrs[y]).addClass("suggest-selected");
								$(suggestTrs[y]).find("td:first").removeClass("suggest-multi-noSelect").addClass("suggest-multi-select");
								break;
							}
						}
					});
				
			}
			this.checkDelayValid(dropdown.getInput(selector));
		},
		showMessage:function(selector,type,op){
			var msg,foot = selector.children('.ccay-selector-foot');
			if(type)
			{
				switch(type)
				{
					case "noMatch":
						msg = Ccay.UI.Config.dropdown.text.noMatch;
						break;
					case "overNum":
						msg = Ccay.UI.Config.dropdown.text.suggestNum.formatText(op.suggestNum);
						break;
				}
			}
			if(msg)
				foot.text(msg).show();
			else
				foot.hide();
		},
		//获取当前焦点所在的文本
		getCurrentText : function(input, split,valueSplit) {
			var text = input.val(),arrValue, arrText, curText, curIndex,
				curSplit = split.trim(),
				pos = Ccay.UI.getInputFocus(input);
			//Ccay.Core.log([pos,input.data('pos')]);
			if (!pos)
				pos = input.data('pos') || 0;
			if (pos > text.length)
				pos = text.length;
			
			if (text.length) {
				arrText = text.split(curSplit);
				arrValue = input.dataValue().split(valueSplit);
				//去空
				for(var i = 0,arrItem;arrItem = arrText[i];i++)
				{
					arrText[i] = arrItem.trim();
				}
				
				var arrTextLen = arrText.length;
				if(Ccay.DataHelper.isEmpty(arrText[arrTextLen - 1]))//去掉最后的空相
					arrText.splice(arrTextLen-1,1);

				if(arrText.length < arrValue.length)//检查录入的文本
					this.checkText(input, arrText, valueSplit);
				
				if(pos == text.length){//当录入的焦点是最后一个时
					curIndex = arrTextLen - 1;
					if(curIndex == 0)
						curIndex = null;
					else
						curText = curIndex < arrText.length ? arrText[curIndex].trim() : '';
				}
				else{
					if (arrTextLen > 0  && arrText.length > 0) {
						var len = 0, splitLen = split.length;
//						for (var i = 0,itemText; itemText = (arrText[i] ? arrText[i].trim() : false ) ; i++) {
						for (var i = 0,itemText; i < arrText.length  ; i++) {
							itemText = arrText[i].trim();
							
							len += itemText.length + splitLen;
							if (pos < len) {
								curText = itemText;
								curIndex = i;
								break;
							}
						}			
					}
				}
			}
			else
				input.dataValue('').data('datas',[]);
			
			return {
				text : curText == void 0 ? text : curText,
				index : curIndex,
				arrText : arrText,
				arrValue:arrValue
			};
		},
		//检查文本，当不匹配时，设置为正确的值
		checkText:function(input,arrText,valueSplit){
			var arrData = input.data('datas');
			var nbsp = $('<div>&nbsp;</div>').text();
			if(arrData && arrData.length){
				var arrCur = [],arrValue=[],cache={};
				//var textCur=[]
				for(var i =0,text=arrText[0];i<arrText.length;i++,text=arrText[i])
				{
					text=text.trim();
					if(text)
					{
						for(var j =0,item,len=arrData.length;j < len;j++)
						{
							item = arrData[j];
							//修复在IE8 上人员空格转换的问题 
							 var reg = new RegExp(String.fromCharCode(160),"g")
                             if(text.replace(nbsp," ").replace(reg," ") == item.text.trim() && !cache[j])
							{
								arrCur.push(item);
								//textCur.push(text);
								arrValue.push(item.value);
								cache[j] = true;
								break;
							}
						}
					}
				}
				var value = arrValue.join(valueSplit),oldValue = input.dataValue();
				if(oldValue != value)
				{
					input.data('datas',arrCur).dataValue(value);
					//input.dataValue(value).val(textCur.join(", ")+", ").data('datas',arrData);
					var selector = dropdown.getSelector(input),op = selector.data('op');
					if(op.fnSelected)
						op.fnSelected.call(input, value, input.val(),oldValue, null,selector);
				}
			}
		},
		//获取正确缓存的数据
		getData:function(input,text,value,valueSplit,index,multiSplit){
			var arrData = input.data('datas'),hasText,arrValue=[];
			
			//兼容reset按钮
			if(arrData && input.val().split(multiSplit).length==1){
				var arr = [];
				arr.push({text:text,value:value});
				return arr;
			}
			
			if(!arrData)
				arrData = [];
			
			if(arrData.length){
				for(var i =0,item=arrData[0];item;i++,item=arrData[i])
				{
					if(value == item.value)
					{
						hasText = true;
						break;
					}
				}
			}
			
			if(!hasText){
				arrData.push({text:text,value:value});
			}
			
			return arrData;
			//input.data('datas',arrData).dataValue(arrValue.join(valueSplit));
		},
		//获取正确顺序的值
		getSortValue:function(arrText,arrData){
			var values = [],cache={};
			if(arrData != null){
				for(var i = 0,len = arrText.length;i < len;i++){
					var text = arrText[i];
					if(text)
					{
						text = text.trim();
						$.each(arrData,function(i,item){
							if(item.text == text && !cache[i]){
								item.value && values.push(item.value );
								cache[i] = true;
								return false;
							}
						})
						
					}
					else
					{
						arrText.splice(i,1);
						i--;
						len--;
					}
				}
			}
			return values;
		},
		//根据文本过滤静态项
		filter:function(text,selector,op,input){
			//Ccay.Core.log("----------------into filter--------")
			selector.data('cached',1);
			var items = selector.find('.'+ op.itemClass);
			//Ccay.Core.log("text:"+text);
			op.cacheReqest !==false && Ccay.UI.matchText(text, items, 
					function(result, item) {
						item.toggleClass('hide', !result).removeClass(op.preSelected);
					});
			var matchItems = items.filter(':not(.hide)'),isPopup = true;
			input.removeData("haschanged");
			if(matchItems.length >1){
				input.data("multiMatch",true)
			}else{
				input.removeData("multiMatch");
				suggestion.validStyle(input);
			}
			//Ccay.Core.log("matchItems.length : "+ matchItems.length);
			if(matchItems.length)
			{
				var fisrtItem = matchItems.eq(0);
				if(matchItems.length == 1 && op.defaultSelect !== false)
				{
					dropdown.itemSeleted(selector,fisrtItem,op);
					selector.hide();
					isPopup = false;
				}
				else
				{
					fisrtItem.addClass(op.preSelected);
					this.showMessage(selector);
					dropdown.setWidth(selector, op,input);
				}	
			}	
			else
			{
				isPopup = false;
				//this.showMessage(selector,"noMatch");
				selector.hide();
				input.valid();
			}
			input.removeData('called').removeData('cached');
			if(input.data("_matching"))
				input.removeData("_matching").valid();
			//Ccay.Core.log("Filter isPopup:"+isPopup+ "  matchItems.length : "+matchItems.length)
			return isPopup;
		},
		//数据选择
		selected : function(value, text, item, selector,data,arrData) {
			
			var input = $(this), op = selector.data('op') ;
			var _testData = {};
			   $.each(arrData||[],function(i,d){
			    _testData[d.value]==undefined && (_testData[d.value] = d.text);
			   });
			//wx200947  当value 存在多个的时候,去重复,修复复制时 会导致人员联想框里面存在相同数据问题
			if(input.hasClass("ccay-user")){
				var curValueArr = value.split(op.valueSplit) ,
					curTextArr = text.split(op.multiSplit),
					itemValue = [],itemText=[];
					
				if(curValueArr.length > 1){
					$.each(curValueArr,function(i,j){
						if( $.inArray(j,itemValue) == -1 ){
							itemValue.push(j);
							itemText.push(_testData[j]);
						}else {
							curTextArr.splice(i,1);
						}
					});
					 itemText.push("");
					value = itemValue.join(op.valueSplit);
					 text = itemText.join(op.multiSplit);
				}
			}
			
			if(value != '' && !arrData){
				//获取焦点所在的项信息
				var cur = suggestion.getCurrentText(input, op.multiSplit,op.valueSplit);
				//判断text是否在已经项中
				//if($.inArray(text, cur.arrText) < 0 || !input.dataValue()){
					if (cur.index != void 0) {
						//已经有选择数据情况下
						if (cur.arrText.length >= cur.index) {
							cur.arrText[cur.index] = text;
							//获取&设置正确的缓存值
							arrData = suggestion.getData(input,text,value,op.valueSplit,cur.index,op.multiSplit);
							//获取争取顺序的value
							value = suggestion.getSortValue(cur.arrText,arrData).join(op.valueSplit);
							
							var curArrText = [];
							if(arrData.length && cur.arrText.length > arrData.length){
								$.each(arrData,function(i,j){
									curArrText.push(j.text);
								})
							}
							
							text = curArrText.length ? curArrText.join(op.multiSplit) : cur.arrText.join(op.multiSplit);
							if (text.lastIndexOf(op.multiSplit) < text.length - op.multiSplit.length)
								text += op.multiSplit;
						}
					} 
					else{
						//不存在选择数据情况下
						if(value){
							arrData = [{text:text,value:value}];
							text += op.multiSplit;
						}
					}
				/*}
				else
				{
					selector.hide();
					return false;
				}*/
			}
			
			/*
			 * lwx200947 当text 跟 value 的个数不匹配时，text 从缓存数据中取。修复 复制 比如dingwenchao WX236530这样数据导致 文本存在多个text 问题
			 * */
			if(value){
				var currTextArr = text.replaceText(" "," ").split(op.multiSplit) ,
					currValueArr = value.split(op.valueSplit);
				
				if(Ccay.DataHelper.isEmpty(currTextArr[currTextArr.length - 1]))//去掉最后的空相
					currTextArr.splice(currTextArr.length-1,1);
					
				if(currTextArr.length != currValueArr.length){
					var currArrDataText = [];
					$.each(arrData,function(i,j){
						currArrDataText.push(j.text);
					});
					text = currArrDataText.join(op.multiSplit);
				}
			}
			/**/
			
			//执行before selected 事件
			if (!op.fnCusBeforeSelected || op.fnCusBeforeSelected.call(input, value, text, item,selector,data) !== false)
			{
				var oldValue = input.dataValue();
				//tip 处理
				dropdown.addTip(input,text);
				input.dataValue(value).val(text).data('datas',arrData);
				//修复可能出现验证失效的情况。
				input.removeData("haschanged").data("oldvalue",text);
				if(text && !input.data("lazyload"))
					input.valid();
				//执行自定义selected方法
				if(op.fnSelected)
					op.fnSelected.call(input, value, text,oldValue, item,selector,data);
			}
			//给联想下拉框添加复选框，设置suggestMulti=true，默认为false。
			if(op.suggestMulti){
				var selectDatas = input.data("datas");
				if(item.children("td.suggestSelect").hasClass("suggest-multi-select")){
					item.removeClass("suggest-selected");
					selector.find(".ccay-suggest-head .suggestSelectAll").parent("tr").removeClass("suggest-selectAll");
					item.children("td.suggestSelect").removeClass("suggest-multi-select").addClass("suggest-multi-noSelect");
					$.each(selectDatas,function(i,d){
						if((d?d.value:d) == item.attr("val")){
							selectDatas.remove(d);
						}
					});
				}else{
					item.addClass("suggest-selected");
					item.children("td.suggestSelect").removeClass("suggest-multi-noSelect").addClass("suggest-multi-select");
					var suggestTrs = selector.find(".ccay-suggest-body tr");
					if(!suggestTrs.find("td:first").hasClass("suggest-multi-noSelect")){
						selector.find(".ccay-suggest-head .suggestSelectAll").parent("tr").addClass("suggest-selectAll");
					}
				}
				var tempSelectValue = "";
				var tempSelectText = "";
				$.each(selectDatas,function(i,d){
					tempSelectValue+=d.value+",";
					tempSelectText+=d.text+op.multiSplit;
				});
				input.dataValue(tempSelectValue.substring(0, tempSelectValue.length-1)).val(tempSelectText);
				
			}else{
				selector.hide();
			}
			return false;
		},
		//请求默认所有数据事件
		callDefault:function(e){
			dropdown.cancelClick(e,1);
			var input = dropdown.getInput(this);
			if(input.isVisiable()){
				var selector = dropdown.getSelector(input),
				op = selector.data('op');	
				//缓存焦点位置
				suggestion.cacheFocus(input,input.val().length);
				
				if(!input.data('called') && !selector.data('isDefault'))
				{
					selector.data('isDefault',1);//是否是默认查询模式,callSelector中判断使用 
					input.data('getDefault',1); //是否是默认查询模式,request中判断使用
					input.data('calledText', '');
					input.data('called',true);
					input.data("round",0);//可清除delayEvent2 绑定但还未执行的事件
					dropdown.sendRequest(selector, op.ajax, input);
					
				
				}
				if(op._type != "sgt" || selector.find(".list-item").length > 0 || input.data("calledText") == "%"){
					dropdown.popup(input, selector, op,true);
				}
			}
		},
		//联想请求事件
		callSelector : function(lazyload) {
			var input = $(this),isRequest;
			// 人员联想的时候添加loading
			if(input.next("a.history").hasClass("hide")){
				input.next("a.history").removeClass("hide");
			}
			if(input.isVisiable()){
				var text = input.validVal(),selector = dropdown.getSelector(input);
				if(selector.length)
				{
					var  op = selector.data('op'),
						callText = input.data('calledText'),
						isPopup = true,
					//是否是默认的全部选择
					isDefault = selector.data('isDefault');
					lazyload || suggestion.cacheFocus(input);
					if(text && callText == text && op.onlyOneRequest !== false)
					{
						isPopup = suggestion.filter(text,selector,op,input);
					}
					else if (callText !== text || isDefault || selector.data('cached') || op.onlyOneRequest === false)
					{
						if (text) {
							if(op.sgtMulti)//多选联想时，根据焦点定位联想的文本项
								text = suggestion.getCurrentText(input, op.multiSplit,op.valueSplit).text;
							//Ccay.Core.log(input.data('called') + " - " + text);
							//判断是否静态过滤
							if(!isDefault && suggestion.checkSuggestText(input,selector,op,text) && op.onlyOneRequest !== false)
							{
								isPopup = suggestion.filter(text,selector,op,input);
							}
							else{
								isRequest = true;
								dropdown.sendRequest(selector, op.ajax, input);
								input.removeData('cached');
							}
						}
						else
							input.removeData('called').removeData('cached').removeData("_matching");
						
						isDefault && selector.data('isDefault',0);
					}
					text && isPopup && dropdown.popup(input, selector, op);
					//Ccay.Core.log("end:" + input.data('called'));
					
					if(op && op.isFocusOutSelector){
						//联想框失去焦点选中第一条联想数据
						$(input).bind( "focusout", function( e ){
							var op = selector.data('op'),
							item = selector.find(':not(.hide).' + op.preSelected + ':first');
							if (!op.fnBeforeBinded || op.fnBeforeBinded(selector, datas, op) !== false) {
								if (selector.isVisiable() && item.length) {
									if (!op.multi)
										selector.hide();
									if (op.fnKeyEnter)
										op.fnKeyEnter(item,input,selector,op);
									else
										dropdown.itemSeleted(selector,item,op);
									
									$(input).unbind("focusout");
								}
							}
						});
					}
				}
			}
		
			//非请求模式下进行延迟加载验证判断
			isRequest || suggestion.checkDelayValid(input);
		},
		checkSuggestText:function(input,selector,op,text){
			//Ccay.Core.log(222);
			var calledText = input.data('calledText');
			
			//Ccay.Core.log([text,calledText,selector.data('total'),op.suggestNum]);
			return calledText && selector.data('total') < op.suggestNum && op.cacheReqest && text.indexOf(calledText) == 0;
		},
		beforeRequest : function(ajax, input, selector) {
			var value, op = selector.data('op'),getDefault = input.data('getDefault');
			//判断是否获取默认的全部查询
			if(getDefault){
				value = op.defaultFilter;
				input.removeData('getDefault');
			}
			else if (ajax.multi) {
				/*var cur = suggestion.getCurrentText(input, op.multiSplit,op.valueSplit);
				value = cur.text;*/
				
				value = suggestion.getCurrentText(input, op.multiSplit,op.valueSplit).text;
			} else
				value = input.val();
				
			if(input.hasClass("placeholder")){
				value = input.attr("search");
			}
				
			//START				
			var cur_value = value , //缓存请求的参数
				curPos = Ccay.UI.getInputFocus(input) , //焦点位置
				inputValue = input.val();//文本值

			//多选的人员联想框，并且输入焦点位置不是文本值的最后
			if(ajax.multi && input.hasClass("ccay-user") && inputValue.length != curPos && value.trim()){
				value = input.val().split(op.multiSplit.trim());
				//去掉最后的空相
				if(Ccay.DataHelper.isEmpty(value[value.length - 1])){
					value.splice(value.length - 1,1);
				}
				//如果缓存没值，则请求参数为当前文本里面的所有值
				if(!input.dataValue()){
					cur_value = value[value.length - 1].trim();
				}else {//如果当前缓存中有值，则请求参数为  当前文本里面的值除却缓存中数据之后  的值
				  var currDatas = input.data("datas") ,
					  currTexts = $.map(currDatas,//得到缓存中的text
							function(obj) {
								return obj.text;
							});
				  var currIndex = -1;
				  //排除在缓存中已存在的text
				  $.each(currTexts,function(i,j){
					currIndex = $.inArray(j,value);
					( currIndex != -1 ) && ( value.splice(currIndex,1) );
				  });
				  cur_value = value[value.length - 1];
			   }
			}
			input.data('calledText', cur_value);
			//END
			
			if ((value && !Ccay.DataHelper.isEmpty(value))  && (getDefault || (value.len ? value.len() : value.join().len()) > op.suggestLength - 1)) {
				var returnObj;
				if (ajax.fnSetRequest) {
					returnObj = ajax.fnSetRequest(ajax, input, selector, value);
					if ($.isPlainObject(returnObj) && !$.isEmptyObject(returnObj))
						return returnObj;
				}
				if (returnObj !== false){
					if(typeof value == "object" && value.length){
						var currParam = [];
						$.each(value,function(i,j){
							currParam.push(dropdown.foramtParam(ajax, value[i].trim(),op.displayField));
						});
						return currParam;
					}else {
						return dropdown.foramtParam(ajax, value,op.displayField);
					}
				}
			}
			return false;
		},
		setValue : function(input, value, text) {
			
			var selector = dropdown.getSelector(input), op = selector.data("op");
			if (Ccay.DataHelper.isEmpty(value))
				dropdown.selected(op, '', '', null, selector, input);
			else {
				value += '';
				//判断是否相同的value
				if (input.dataValue() !== value) {
					input.dataValue(value);
					if (text == void 0) {
						input.val(value);
						//是否加载之后根据value初始化input 文本
						if (op.initInput) {
							//自定义获取text的ajax处理
							if (op.getTextAjax) {
								if (!op.getTextAjax.type)
									op.getTextAjax.type = "POST";
								
								op.getTextAjax.data = value.split(op.valueSplit);
								
								if (!op.getTextAjax.success)
									op.getTextAjax.success = function(result) {
										
										if(op.sgtMulti && op.sort == "default"){
											var array = new Array() , val = input.data("value").split(op.valueSplit);
											for(var k=0;k<val.length;k++){
												$.each(result,function(i,j){
													if(j[input.attr("valueField")] == val[k]){
														array.push(j);
													}
												})
											}
										}
										
										var data = Ccay.UI.getValueText(array ? array : result, op);
										//input.dataValue(data.value).val(data.text).data('calledText',data.text);
										input.removeData('called');
										suggestion.setCurValue(op, data.value, data.text, null, selector, input);
									};
									dropdown.ajax(op.getTextAjax,input);
							} else {
								selector.data('initInput', input);
								op.fnCallSelector.call(input);
							}
						}
						else
							dropdown.selected(op, value, value, null, selector, input);
					}
					else
						this.setCurValue(op, value, text, null, selector, input);
				}
			}
			return input;
		},
		//设置联想组件中正确的value
		setCurValue:function(op,value, text, item, selector, input){ 
			if(op.sgtMulti)//判断是否是多项联想
			{ 
				if(value && text){
					var arrText = text.split(op.multiSplit.trim()),
					arrValue = value.split(op.valueSplit),
					curValue,arrData = [];
					
					var arrTextLen = arrText.length;
					if(Ccay.DataHelper.isEmpty(arrText[arrTextLen - 1]))//去掉最后的空相
						arrText.splice(arrTextLen-1,1);
						
					var len = arrText.length > arrValue.length ? arrValue.length : arrText.length;
				
					for(var i =0;i < len;i++){
						if(curValue = arrValue[i])
							arrData.push({value:curValue,text:arrText[i].trim()});
					}
					//text += op.multiSplit;
					var cur_Index = text.length - op.multiSplit.length ,
						bool = text.lastIndexOf(op.multiSplit.trim()) == cur_Index ;
					!bool && (text += op.multiSplit);
				}
				input.dataValue(value).val(text).data('datas',arrData).removeClass("error").removeData("multiMatch");
				//修复可能出现验证失效的情况。
				input.removeData("haschanged").data("oldvalue",text);
				suggestion.validStyle(input);
			}
			else
			{
				//input.data('datas',text);
				dropdown.selected(op, value, text, null, selector, input);
			}
				
		},
		//检查延迟验证功能
		checkDelayValid:function(input){
			var op = dropdown.getSelector(input).data('op');
			input.removeData('called');
			if(input.data("_matching"))
			{
				input.removeData("_matching");
				if(input[0] == document.activeElement){
					if(!op){
						input.clearValid();
					}else if(op.defaultSelect !== false)
						input.clearValid();
				}else
					input.valid();
				//input.hasClass("error-ctr") && input.valid();
			}
		},
		//验证方法
		validInput:function(input){
			var text = input.validVal().trim(),result = true;
			if(text)
			{
				var op = dropdown.getSelector(input).data('op');
				if(!op){
					return true;
				}
				//如果nopending为true 则不走pending模式
				if(op.nopending !== true ){
					//判断是否是匹配中的状态，设置延迟验证
					if(input.data("_matching") || input.data("haschanged"))
					{
						input.data("_delayValid",true);
						input.removeData("multiMatch");
						suggestion.validStyle(input);
						//Ccay.Core.log("pending");
						return "pending";
						//return true;
					}
					else
						input.removeData("_delayValid");
				
				}
				if(op.sgtMulti){
					//根据缓存的数据进行验证
					var arrData = input.data('datas'),errorMsg;
						var split = op.multiSplit.trim(),matchText,curText = [];
						if(arrData && arrData.length){
							var error = [],cur_arrData = $.extend([] , arrData);
							//lwx200947  添加 replaceText(" "," ") 修复去空无效、拆分、替换失效问题,勿删，这两个空格不是一样的，类似 trim 这样的方法对第一个空格无效
							$.each(arrData,function(i,n){
								n.text = n.text.replaceText(" "," ");
								
								if(n.text.indexOf(op.multiSplit) != -1 && n.value.indexOf(op.valueSplit) != -1){
									//如果text 跟 value 里面包含分隔符，则进行拆分，重新组装 arrData
									var cur_text = n.text.split(op.multiSplit) ,
										cur_value = n.value.split(op.valueSplit);
										
									if(Ccay.DataHelper.isEmpty(cur_text[cur_text.length - 1]))//去掉text最后的空相
										cur_text.splice(cur_text.length-1,1);
										
									if(Ccay.DataHelper.isEmpty(cur_value[cur_value.length - 1]))//去掉value最后的空相
										cur_value.splice(cur_value.length-1,1);
										
									if(cur_text.length == cur_value.length){
										//移除掉原来的，把新组成的对象push 进集合对象
										cur_arrData.splice(i,1);
										for(var k = 0,item = cur_text[0] ; item ; k++,item = cur_text[k]){
											cur_arrData.push({value:cur_value[k] , text:item});
											curText.push(item.trim());
										}
									}
								}else {
									curText.push(n.text.trim());
								}
							});
							//重置缓存数据集合，并进行缓存
							arrData = cur_arrData;
							input.data('datas',arrData);
							
							curText = split + curText.join(split) + split;
							text = text.replaceText(op.multiSplit,split).split(split);
							for(var j =0,len=text.length;j < len;j++)
							{
								//var matchText = text[j].trim();
								var matchText = text[j].replaceText(" "," ").trim();
								if(matchText){
									if(curText.indexOf(split + matchText + split) < 0)
										error.push(matchText);
								}
							}
							if(error.length)
							{
								errorMsg = error.join(";")
								result = false;
							}
						}
						else
							result = false;
						//校正text与value的匹配
						suggestion.checkText(input, text, op.valueSplit);
				}
				else
					result = dropdown.validInput(input);
			}
			suggestion.validStyle(input);
			if(!result){
				//input.dataValue("");
				if(dropdown.getTrigger(input).hasClass("warning")){
					return "";
				}else{
					input.attr("error_msg",errorMsg || text);
				}
			}
			//Ccay.Core.log("result:"+result);
			return result;
		},
		//处理enter键即时联想操作
		keyEnter:function(item,input,selector,op){
			var calledText = input.data('calledText'),text;
			if (op.sgtMulti)
				text = suggestion.getCurrentText(input, op.multiSplit,op.valueSplit).text;
			else
				text = input.validVal();
			
			if(text.length && calledText != op.defaultFilter && text.indexOf(calledText) < 0){
				input.data('called',1);
				op.fnCallSelector.call(input);
			}
			else
				dropdown.itemSeleted(selector,item,op);
		},
		//复制粘贴事件
		onPaste:function(e){
			var input = $(this),oldValue = input.validVal(),selector = dropdown.getSelector(input),
				op=selector.data("op");
				
				if(input.hasClass("placeholder")){
					input.attr("search",input.val());
				}
				
				setTimeout(function(){
					if(op.sgtMulti){
						//复制事件清除延迟加载和初始化赋值设置
						selector.removeData("lazyload");
						input.removeData("initInput");
						
						//获取需要匹配的文本
						var matchText = input.validVal(),split = op.multiSplit.trim();
							matchText = matchText.replaceText(op.multiSplit,split).split(split);
						//当有多项时触发匹配事件
						
						if(matchText.length > 1){
							input.val(oldValue).data("nocall",1);
							suggestion.matchPaste(input,selector,op, matchText,oldValue);
						}
						else
						{
							selector.data('lazyload',true);
							dropdown.matchInput.call(input,e,true);
						}
					}
					else
					{
						selector.data('lazyload',true);
						dropdown.matchInput.call(input,e,true);
					}
				},10);

		},
		//匹配事件
		matchPaste:function(input,selector,op,matchText,oldValue){
			var curText,emptyNum=0,
				matchData = { values:[], errors:[], choose:[]},
				arrData = input.data('datas');
 
			//判断是否超过了最大的粘贴限制
			if(this.checkMatchText(matchText, arrData) > op.maxParseMatch)
			{
				input.val(oldValue);
				Ccay.UI.showMessage($i18n("ccay.common.validate.suggestParse").format(op.maxParseMatch),"error");
				return false;
			}
			for(var i =0,len = matchText.length;i<len;i++){
				var text = matchText[i].trim();
				//判断是否已经匹配过
				if(text.length && Ccay.Format.getArrayItem(text,arrData,"text") == null)
				{
					var ajax = dropdown.foramtParam(op.ajax, text, op.displayField),
						fnCheckEnd = function(){//判断是否完成所有服务端匹配的方法
							if(matchData.values.length + matchData.errors.length + matchData.choose.length + emptyNum == len)
								suggestion.endParseMatch(input,selector,op,matchData,matchText);
						};
					this.setParseAjax(input, op,ajax, text, matchData,fnCheckEnd,i)
					input.parent().loading();
				
					Ccay.UI.ajax(ajax);
				}
				else
				{
					emptyNum++;
				}	
			}
			if(emptyNum == len)
				suggestion.endParseMatch(input,selector,op,matchData,matchText);
		},
		checkMatchText:function(matchText,arrData){
			var num = 0;
			for(var i =0,len = matchText.length;i<len;i++){
				var text = matchText[i].trim();
				//判断是否已经匹配过
				if(text.length && Ccay.Format.getArrayItem(text,arrData,"text") == null)
				{
					num++;
				}
			}
			return num;
		},
		//设置粘贴的请求ajax
		setParseAjax:function(input,op,ajax,text,matchData,fnCheckEnd,i){
			ajax.success = function(result){
				var data = result ? (result.result || result) : [];
				if(data.length)
				{
					if(data.length == 1)
						matchData.values.push({index:i,value:data[0][op.valueField],text:data[0][op.displayField],oldText:text,data:data[0]});
					else
						matchData.choose.push({index:i,text:text,data:data});
				}
				else
					matchData.errors.push({index:i,text:text});
				//记录请求的文本
				input.data('calledText', text);
				fnCheckEnd();
			}
			ajax.error = function(){
				matchData.errors.push({index:i,text:text});
				fnCheckEnd();
				return true;
			}
			ajax.loading = false;
		},
		//结束粘贴请求的操作
		endParseMatch:function(input,selector,op,matchData,matchText){
			input.removeData("_matching").parent().loadingClose();
			//判断是否全部匹配，否则开启确认对话框
			if(matchData.choose.length || matchData.errors.length)
				this.openChoose(matchData, input, selector, op,matchText);
			else
				this.setChooseValue(input,selector,op,matchText,matchData);
			input.removeData("nocall").removeData('copy');
		},
		//设置匹配之后的value
		setChooseValue:function(input,selector,op,matchText,matchData){
			var emptyDT,newArrData = [],cacheData = [];
			if(matchData.values.length){
				$.each(matchData.values,function(i,n){
					if(n.text != null){
						matchText[n.index] = n.text;
						newArrData.push({value:n.value,text:n.text});
						cacheData.push(n.data);
					}
					else{
						matchText[n.index] = null;
					}	
				})	
			}
			//suggestion.setParseValue(input,selector,op,matchText,newArrData,cacheData);
			var arrData = (input.data('datas') || []).concat(newArrData),
			value = suggestion.getSortValue(matchText,arrData).join(op.valueSplit);
			
			this.selected.call(input,value,matchText.length > 0 ? (matchText.join(op.multiSplit) + op.multiSplit) : '', null, selector,cacheData, arrData);
		},
		//打开选择匹配项的对话框
		openChoose:function(matchData,input,selector,op,matchText){
			Ccay.UI.dialog(null,"ccay.common.suggest.parseConfirm",{
				width:600,
				content:"<div id='suggest_parseResult' class='ccay-selector-body'><dl id='suggest_choose'></dl></div>",
				fnLoad:function(panel){
					suggestion.buildChooseList(panel,matchData,matchText,input,selector,op);
				},
				okClick:function(panel){
					suggestion.getChoose(panel,matchData,input,selector,op,matchText,this);
					this.close();
				}
			});
		},
		//生成匹配选择项
		buildChooseList:function(panel,matchData,matchText,input,selector,op){
			var html=[];
			//生成匹配项
			$.each(matchData.values,function(i,n){
				html.push("<dt class='matched' _index='",i,"'>[√] ",n.oldText.encode(),' : <span>',n.text.encode(),'</span><a class="ccay-icon del"></a></dt>');
			});
			//生成未匹配项
			$.each(matchData.errors,function(i,n){
				html.push("<dt class='non-match' _index='",i,"'>[×] ",n.text.encode(),'<a class="ccay-icon del"></a></dt>');
			});
			//生成有多个匹配项
			$.each(matchData.choose,function(i,n){
				html.push("<dt class='choose-match' _index='",i,"'>[...] <samp class='toggle-choose'>",n.text.encode(),' : </samp><span></span><a class="ccay-icon del"></a></dt><dd>',op.panelBegin,Ccay.UI.tmplList(op.item, n.data),op.panelEnd,'</dd>');
			});
			panel.find('#suggest_choose').html(html.join(''))
			//选择事件
			.delegate('.list-item','click',function(){
				var item = $(this),selected,text,dd = item.parents('dd:first'),dt= dd.prev();
				if(item.hasClass('selected'))
				{
					item.removeClass('selected');
					text = "";
				}
				else{
					selected = true;
					item.parent().children('.selected').removeClass('selected');
					item.addClass('selected');
					text = item.find('.list-text').text();
					dt.addClass('closed');
					dd.hide();
				}
				dt.children('span').text(text);
			})
			//隐藏/显示选择项事件
			.delegate('.toggle-choose','click',function(){
				var dt = $(this).parent().toggleClass('closed'),open = !dt.hasClass("closed");
				dt.next().toggle(open);
			})
			//删除事件
			.delegate('.del','click',function(e){
				var dt = $(this).parent();
				suggestion.deleteItem(dt,matchData,matchText);
				e.stopPropagation();
			});
		},
		//删除匹配项
		deleteItem:function(dt,matchData,matchText){
			var index = dt.attr('_index') * 1,isChoose,item;
			if(dt.hasClass('matched'))
				item = matchData.values[index];
			else if(dt.hasClass('non-match'))
				item = matchData.errors[index];
			else if(dt.hasClass('choose-match'))
			{
				isChoose = true;
				item = matchData.choose[index];
			}
			matchText[item.index] = null;
			item.text = null;
			isChoose && dt.next().remove();
			dt.remove();
		},
		//获取有多个匹配项的选择的数据
		getChoose:function(panel,matchData,input,selector,op,matchText,btn){
			var emptyDT;
			$('#suggest_choose > dt.choose-match').each(function(i){
				var dt = $(this),index = dt.attr('_index') * 1,text = dt.children("span").text();
				if(text.length){
					var item = matchData.choose[index],selectData = Ccay.Format.getArrayItem(text, item.data, op.displayField);
					if(selectData){
						var value = selectData[op.valueField];
						matchData.values.push({index:item.index,value:value,text:text,data:selectData});
					}
				}
				else
					emptyDT = dt;
			});
			if(emptyDT)
			{
				Ccay.UI.confirm("ccay.common.suggest.confirmNonChoose",function(result){
					if(result)
					{
						suggestion.setChooseValue(input,selector,op,matchText,matchData);
						Ccay.UI.dialog.triggerCancel(btn);
					}
					else
					{
						emptyDT.parent().parent().scrollTop(emptyDT.position().top - 20);
					}
				})
			}
			else{
				suggestion.setChooseValue(input,selector,op,matchText,matchData);
				Ccay.UI.dialog.triggerCancel(btn);
			}
		},
		
		validStyle : function(input){
			var trigger = dropdown.getTrigger(input);
			if(input.data("multiMatch") && input.validVal().trim() && input.data("calledText")!="%" && dropdown.validInput(input) !== true){
				!input.hasClass("error") && input.addClass("error");
				!trigger.hasClass("warning") && trigger.addClass("warning");
				//Ccay.Core.log("add warning");
			}else{
				trigger.removeClass("warning")
				//Ccay.Core.log("remove warning");
			}
		}
		
		
	};

	$.fn.suggestion = function(ops) {
		var op = $.extend(true, {
			delay : Ccay.UI.Config.dropdown.suggestDelay,
			multi : false, // 是否允许多项联想
			showTrigger:true,
			suggestLength : 0, // 输入字符长度进行联想
			defaultFilter: "%", //默认过滤条件
			pasteMatch:true,	//是否进行粘贴匹配,
			suggestNum:Ccay.UI.Config.dropdown.suggestNum,
			maxParseMatch:Ccay.UI.Config.dropdown.maxParseMatch,
			clearRepeating : Ccay.UI.Config.dropdown.clearRepeating,
			cacheReqest:true,
			initInput : false,
			suggestMulti :false,  // suggest联想下拉框添加复选框
			isFocusOutSelector:false,//是否失去焦点选中第一条联想数据
			getTextAjax:null
				// ,multiSplit: Ccay.Config.Format.textSplit
			}, ops);
		var isMulti = op.multi;
		op.sgtMulti = isMulti;
		
		$.extend(op, {
					multi : false,
					onlyone : false, // 是否使用唯一模式，既只会生成一个selector
					combo : false, // combo模式
					lazyload : true,
					fnSetTrigger : suggestion.setTrigger, // 设置填出选择触发器的方法
					fnCallSelector : suggestion.callSelector,
					fnKeyEnter:suggestion.keyEnter,
					_type:'sgt',
					css : null
				});

		this.cacheSet(op, 'delay');

		if (op.ajax && op.ajax.url) {
			op.ajax.url = op.ajax.url.formatField({suggestNum:op.suggestNum,connect:"${connect}"});
			if (op.ajax.beforeRequest) {
				var fnBeforeReques = op.ajax.beforeRequest;
				op.ajax.fnSetRequest = fnBeforeReques;
			}
			op.ajax.beforeRequest = suggestion.beforeRequest;
			
			var fnBinded =  op.fnBinded;
			op.fnBinded = function(selector, datas){
				suggestion.selectedBinded(selector, datas);
				fnBinded && fnBinded(selector, datas);
			}
			
			if (isMulti) {
				op.ajax.multi = true;
				if (op.fnBeforeSelected) {
					var fnBeforeSelected = op.fnBeforeSelected;
					op.fnCusBeforeSelected = fnBeforeSelected;
				}
				op.fnBeforeSelected = suggestion.selected;
			}

			return this.each(function() {
				var input = $(this);
				input.dropdown(op).removeAttr('readonly').managerReg('suggestion',true);
				op.readOnly && input.attr("readonly","readonly");

				if(!input.hasClass('ccay-suggest'))
					input.addClass('ccay-suggest');
				
				$(input.data('selector')).removeData('lazyload');
				input.bind("focus",function(){
					var selector = dropdown.getSelector($(this));
					selector.removeData("notValid");
					if(input.hasClass("placeholder")){
						if(input.val() == input.attr("placeholder")){
							$(this).val("").removeClass("filter-gray");
						}
					}
					
					var ctr = $(this),val = ctr.val().trim();
					var focustime = ctr.attr("focustime");
					if(focustime && new Date() - focustime * 1 < 100){
						return;
					}
					var trigger = dropdown.getTrigger(ctr)
					if(!ctr.val() && trigger.hasClass("history hide") && Ccay.History.hasHistory(op) ){
						var history = Ccay.History.getHistory(op.historyKey || ( op.ajax && op.ajax.url ));
						if(history.length > 1 ||  history[0].data)
							trigger.removeClass("hide");
					}
					if(!val){
						ctr.removeData("haschanged").removeData("multiMatch");
						suggestion.validStyle(ctr);
						return;
					}
					setTimeout(function(){
						ctr.data("_delayValid") && ctr.data("_matching") && ctr.removeData("_delayValid");
						if(dropdown.getTrigger(ctr).hasClass("warning") &&  !dropdown.getSelector(ctr).is(":visible")){
							
							Ccay.UI.setInputFocus(ctr.attr("focustime",new Date().getTime()));
							if(!ctr.data("called") && op.fnCallSelector){
								Ccay.UI.setInputFocus(ctr,ctr.data("lastFocusIndex"));
								op.fnCallSelector.call(ctr,true);
							}
						}
					},0);
				}).bind("blur",function(e){
					var ctr = $(this), op = dropdown.getSelector(ctr).data('op'),val = ctr.val().trim();
					
					if(ctr.hasClass("placeholder")){
						if(!val){
								setTimeout(function(){
									ctr.addClass("filter-gray").val(ctr.attr("placeholder"));
									ctr.removeData("haschanged").removeData("multiMatch").removeClass("error");
								},50);
								return;
						}
					}
					
					if(!ctr.data("called") &&  document.activeElement !== ctr[0]){
						var text = suggestion.getCurrentText(ctr, op.multiSplit,op.valueSplit).text;
						if(!text.length || text.length < op.suggestLength){
							ctr.removeData("haschanged").removeData("multiMatch").removeClass("error");
							var selector = dropdown.getSelector(ctr);
							!selector.data("notValid") && ctr.valid();
							selector.removeData("notValid");
							if(ctr.parents(".gt-grid").length){
								ctr.next("label.error").remove();
							}
							return;
						}
						if(ctr.data("haschanged") && !ctr.data("called") && op.fnCallSelector){
							//input.data('called',1);
							ctr.removeData('calledText').data("round",0);
							dropdown.clearInterval(op);
							op.fnCallSelector.call(ctr,true);
							//input.removeData("haschanged").removeData("multiMatch");
						}
						if(ctr.data("haschanged")){
							suggestion.validStyle(ctr);
						}
						if(ctr.parents(".gt-grid").length && ctr.hasClass("error")){
							ctr.next("label.error").show();
						}
					}
				});
				dropdown.setTrigger(input, suggestion.callDefault,null,op);
				op.pasteMatch && input.bind("paste",suggestion.onPaste)
			});
		}
	}

	$.validator.addMethod("ccay-suggest", function(value, element) {
				return suggestion.validInput($(element));
			});
	// 注册manager
	Ccay.UI.regManager('suggestion', {
				setValue : function(value, text) {
					return suggestion.setValue(this.ctr, value, text);
				},
				getText:function(){
					var text = this.ctr.val();
					if(text)
					{
						var op = dropdown.getSelector(this.ctr).data("op");
						if(op.sgtMulti && op.clearRepeating !== false){
							var	arr = text.split(op.multiSplit);
							if(arr.length > 1)
								return arr.clearRepeating().join(op.multiSplit);
						}
					}
					return text;
				},
				getValue:function(){
					
					var value = this.ctr.dataValue();
					if(value)
					{
						var op = dropdown.getSelector(this.ctr).data("op");
						//当验证不通过时
						if(suggestion.validInput(this.ctr) !== true)
						{
							//单选返回空
							if(!op.sgtMulti)
							{
								return '';
							}
						}
							
						if(op.sgtMulti && op.clearRepeating !== false){ 
							var arr = value.split(op.valueSplit);
							if(arr.length > 1)
								return arr.clearRepeating().join(op.valueSplit);
						}
					}
					return value;
				},
				getSelector:function(){
					return dropdown.getSelector(this.ctr);
				},
				valid : function() {
					return suggestion.validInput(this.ctr);
				},
				disabled : function(enabled) {
					return dropdown.disabled(this.ctr, enabled);
				},
				lock:function(input,locked){
					input.data("ddl_locked",locked); 
				},
				hide:function(visiable){
					var operate = visiable ? "show" : "hide";
					this.ctr[operate]();
					visiable || dropdown.getSelector(this.ctr).hide();
					dropdown.getTrigger(this.ctr)[operate]();
				},
				readonly:function(enabled){
					return dropdown.readonly(this.ctr, enabled);
				}
				//取消请求操作
//				cancelRequest:function(enable){
//					this.ctr.data("cancelRequest",enable !== false ? true : null);
//				}
			});

	var richSelector = {
		init : function(selector, op) {
			if (op.richMode) {
				if (op.richMode.url) {// load模式
					op.combo = false;

					if (op.richMode.mode == 'dialog') {
						// op.onlyone = false;
						op.fnCallSelector = richSelector.callDialog;
					} else
						richSelector.createLoad(selector, op);
				} else if (op.richMode.mode) {// create模式
					selector.addClass('ccay-selector-' + op.richMode.mode).data('step', 1);

					var input = dropdown.getInput(selector), id = selector.id() + '_con', 
						container = $.create(op.richMode.mode == 'tree' ? 'ul' : 'div')
								.id(id).appendTo(dropdown.getSelectorBody(selector)).click(function(e) {
										e.stopPropagation();
									});
					
					if (op.delay < 1000)
						op.delay = 1000;

					op.multi = false;
					op.fnCallSelector = richSelector.callSelector;
					if (op.combo) {
						op.fnMatchInput = null;
						input.data('setValue', 0);
						//Ccay.UI.delayEvent(input, 'keyup',richSelector.callSelector, op.delay,Ccay.UI.isKeyDownValue);
						//  修复下拉选择数据回车  下拉数据再次弹出  
						Ccay.UI.delayEvent(input, 'keyup',richSelector.callSelector, op.delay,function(e, trigger){
				               return Ccay.UI.isKeyDownValue(e, trigger) && e.keyCode != 13;
			             });
					}
					if (op.richMode.mode == 'grid') {
						op.itemClass = 'gt-row';
						op.preSelected = 'gt-row-selected';
						op.fnKeyEnter = function(item,input,selector,op){
							richSelector.gridRowClick(item,input,selector);
						} 
					}
					// else if(op.richMode.mode == 'tree')
					// {
					// container.width(op.richMode.op.width);
					// }
				}
			}
		},
		callSelector : function(e) {
			if (e && e.type == 'click')
				dropdown.cancelClick(e,1);

			var input = dropdown.getInput(this), selector = dropdown.getSelector(input),
				op = selector.data('op'), step = selector.data('step');
			selector.data('_inpop',true);
			if(e && e.type == 'click' || selector.is(":visible") || input.val().trim()){
				if (op.richMode && op.richMode.mode == 'tree')
					richSelector.initTree(input, selector, op, step,(e && e.type == 'click'));
				else
					richSelector.initGrid(input, selector, op, step);
				if (step == 1) {
					if (op.combo)
						selector.data('step', 2);
					else
						selector.removeData('step');
				}
				input.data("round",false);
				dropdown.popup(input, selector, op);
				selector.removeData('_inpop');
			}
		},
		initGrid : function(input, selector, op, step) {
			if (step == 1) {
				var gridOp = op.richMode.op;
				gridOp.onRowClick = richSelector.gridRowClick;

				if (op.combo) {// combo模式中过滤处理
					var filterField = gridOp.operation.search.filterField;
					if (filterField) {
						gridOp.operation.search.fnload = function(url, param,fnRefresh) {
							param = {};
							param[filterField] = input.val();
							Ccay.doGet(url, param, fnRefresh);
						}
					}
				}
				dropdown.getSelectorBody(selector).children().ccayGrid(gridOp);
				selector.width(op.richMode.op.width);
				op.richMode = null;
			} else if (step == 2)// 过滤处理
				dropdown.getSelectorBody(selector).children().ccayGridSearch();
		},
		gridRowClick : function(value, record, cell,row) {
			var tr = $(row || value);
			if (tr.length) {
				var value = tr.find('span.ccay-selector-value').text(), 
					text = tr.find('span.ccay-selector-text').text();

				var selector = tr.parents('.ccay-selector'), op = selector.data('op'), input = dropdown.getInput(selector);
				dropdown.selected(op, value, text, tr, selector, input);
			}
		},
		initTree : function(input, selector, op, step, isTrigger) {
			if (step == 1 || op.connector) {
				var treeOp = op.richMode.op,selectorBody = dropdown.getSelectorBody(selector);
				treeOp.setting || (treeOp.setting = {});
				treeOp.setting.onClick = richSelector.TreeClick;
				treeOp.setting.beforeCollapse = treeOp.setting.beforeExpand = function(){
					setTimeout(function(){
						selector.focus();
					},0);
				};
				/**
				 * 
				 * @time 2014-06-13
				 * @desc igrid中级联tree传值问题。
				 */ 
				var treeOpUrl = treeOp.url;
			    if(op.connector){
			    	var conValue = op.fnGetConnectValue ? op.fnGetConnectValue(input,op) : dropdown.getConnectValues(op.connector);
			    	treeOpUrl = treeOpUrl.format(conValue);
			    	if(conValue){
			    		selectorBody.children().ccayTree(treeOpUrl, treeOp.setting,treeOp.callback);
			    	}
			    }else{
			    	var value = input.val().trim();
					if(value != (input.data("oldFilterValue") || "")){
						input.data("oldFilterValue",value);
						treeOp.setting.filterDataValue = value;
						input.data("round",false);
					}
			    	selectorBody.children().ccayTree(treeOpUrl, treeOp.setting,treeOp.callback);
			    }
				selector.width(op.richMode.op.width);
			}  
			else if (step == 2 && !isTrigger)// 过滤处理
			{
				var value = input.val().trim();
				if(value != (input.data("oldFilterValue") || "")){
					input.data("oldFilterValue",value);
					Ccay.UI.treeFilter(dropdown.getSelectorBody(selector).children(), value,true,false);
					input.data("round",false);
				}
			}
			richSelector.initTreeMoveEvent(input, selector,false);

		},
		initTreeMoveEvent : function(input, selector,isMulti){
			var fn;
			!input.attr("treemove") && input.attr("treemove",true).bind("keydown.treemove",fn = function(e){
				var currCtrl = $(this),selector,input,keycode = e.keyCode;
				if(!(keycode >= 37 && keycode <=40 || keycode == 13 || keycode == 32) ){
					return;
				}
				if(currCtrl.is("input")){
					input = currCtrl;
					selector = dropdown.getSelector(input);
					if(keycode >= 37 && keycode <=40 || keycode == 13 ){
						selector.data('_active',true);
						selector.show().focus().show();
						setTimeout(function(){
							selector.show().focus()
							selector.data('_active',null);
							var tree = selector.find(".ztree:first"), manager = tree.getCcayTreeManager(),
							currA = tree.find("a[treeNode_a].curSelectedNode");
							if(!currA.is(":visible")){
								currA.removeClass("curSelectedNode");
								currA.not("a");
							}
							if(currA.length == 0){
								if(isMulti){
									selector.find(".ztree:first").find("a[treeNode_a]:first").click();
								}else{
									selector.find(".ztree:first").find("a[treeNode_a]:first").addClass("curSelectedNode");
								}
							}
						},200)
						return false;
					}
				}else{	
					selector = currCtrl;
				}
				if(selector.length == 0 || !selector.is(":visible"))
					return;
				var tree = selector.find(".ztree:first"), manager = tree.getCcayTreeManager(),
				currA = tree.find("a[treeNode_a].curSelectedNode"),currNode,moveToNode;
				
				if(!currA.is(":visible")){
					currA.removeClass("curSelectedNode");
					currA.not("a");
				}
				var currLiNode = currA.parent("li"),moveNode;
				if(currLiNode.length  && (keycode == 37 || keycode == 39)){
					var node = manager.getNodeByTId(currA.parent().prop("id")), right = keycode == 39;
					if(node.isParent){
						right && !node.open && currLiNode.find("button[treeNode_switch]:first").click();
						!right && node.open && currLiNode.find("button[treeNode_switch]:first").click();
	
					}else if(!right){
						var parentLi = currLiNode.parent().parent();
						if(parentLi.length > 0){
							if(isMulti){
								parentLi.children("a:first").click();
							}else{
								parentLi.children("a:first").addClass("curSelectedNode");
								currLiNode.children("a:first").removeClass("curSelectedNode");
							}
						}
					}
					selector.focus();
					return false;
				}else if(keycode == 38){
					if(currLiNode.length > 0){
						moveNode = richSelector.treeMove(currLiNode,"prev",tree,isMulti);
					}else{
						tree.find("a[treeNode_a]:first").addClass("curSelectedNode");
					}
				}else if(keycode == 40){
					if(currLiNode.length > 0){
						moveNode=  richSelector.treeMove(currLiNode,"next",tree,isMulti);
					}else{
						tree.find("a[treeNode_a]:first").addClass("curSelectedNode");
					}
				}else if(keycode == 13){
					if(selector.find('.ccay-selector-operate > input').length > 0){
						selector.find('.ccay-selector-operate > input').click();
					}else{
						currLiNode.find("a:first").click();
						
					}
				}else if(keycode == 32){
					currLiNode.children("button[treeNode_check]").click();
					return false;
				}
				var hei = 25;
				if((keycode == 38 || keycode == 40) && moveNode && moveNode.length > 0){
					if(isMulti){
						var pager = selector.find(".ccay-selector-page");
						if(moveNode.position().top < 0){
							pager.scrollTop(pager.scrollTop() + moveNode.position().top);
						}else if(moveNode.position().top + hei > pager.height()){
							pager.scrollTop(pager.scrollTop() + moveNode.position().top + hei - pager.height());
						}
					}else{
					
						if(tree.offset().top - moveNode.offset().top > 0){
							tree.scrollTop(tree.scrollTop() - (tree.offset().top - moveNode.offset().top) );
						}else if(moveNode.offset().top + hei> tree.offset().top + tree.height()){
							tree.scrollTop(tree.scrollTop() + (moveNode.offset().top - tree.offset().top - tree.height()) +  hei);
						}
					}
				}
				return false;
			})
			!selector.attr("treemove") && selector.attr("treemove",true).bind("keydown.treemove",fn);
		
		},
		treeMove: function(currLiNode,type,tree,isMulti){
			var allNode = tree.find("li:visible"),moveNode,currId = currLiNode.prop("id");
			allNode.each(function(i){
				if(this.id == currId){
					moveNode = type == "next" ? allNode[i + 1] :  allNode[i - 1];
					
					if(moveNode){
						if(isMulti){
							$(moveNode).children("a:first").click();
							currLiNode.children("a:first").removeClass("curSelectedNode");
						}else{
							$(moveNode).children("a:first").addClass("curSelectedNode");
							currLiNode.children("a:first").removeClass("curSelectedNode");
						}
					}
					return false;
				}
			})
			return $(moveNode);
		}, 
		TreeClick : function(e, treeId, treeNode) {
			var selector = $('#' + treeId).parent().parent(), op = selector.data('op'), 
				input = dropdown.getInput(selector), treeOp = op.richMode.op, value, text;
			selector.find("a.curSelectedNode").not("#"+treeNode.tId+"_a").removeClass("curSelectedNode");
			text = treeNode[op.displayField];
			value = treeNode[op.valueField];
			if(treeOp.fnSelected &&!treeOp.fnSelected(treeNode)){
				return null;
			}
			dropdown.selected(op, value, text, treeNode, selector, input);
			setTimeout(function(){
				input.focus();
			},300);
			
		},
		createLoad : function(selector, op) {
			op.fnCallSelector = richSelector.callPage;
			//debugger;
			var selectorBody = selector.addClass('ccay-selector-load').children('.ccay-selector-body').width(op.richMode.width).height(op.richMode.height + 30);

			var pagePanel = $.create('div').addClass('ccay-selector-page')
					.height(op.richMode.height).appendTo(selectorBody), 
					toolPanel = $.create('div').addClass('ccay-selector-operate')
					.html(Ccay.UI.button('ccay.common.button.ok')).appendTo(selectorBody);
		},
		callPage : function(e) {
			dropdown.cancelClick(e,1);
			var input = dropdown.getInput(this), selector = dropdown.getSelector(input), 
				op = selector.data('op'), isSetValue;
			if (op.richMode.url) {
				selector.find('.ccay-selector-page').ccayLoad(op.richMode.url,
						function() {
							var fnSetSelected = selector.data('fnSetSelected');
							fnSetSelected && fnSetSelected(input.dataValue(), input.val());
							if(selector.find("div.ztree,ul.ztree").length){
									selector.find(".ccay-selector-page").css("margin-bottom",30);
									richSelector.initTreeMoveEvent(input, selector,true);
							}
						},true);
				op.richMode.url = null;
			} else
				isSetValue = true;
			dropdown.popup(input, selector, op);

			if (isSetValue) {
				var btn = selector.find('.ccay-selector-operate > input');
				if (btn.data('fnSetSelected')){
					btn.data('fnSetSelected')();
				}
			}
		},
		callDialog : function(e) {
			dropdown.cancelClick(e,1);
			var input = dropdown.getInput(this), selector = dropdown.getSelector(input), 
				op = selector.data('op');
			if (op.richMode.url) {
				Ccay.UI.dialog(op.richMode.url, "Selector", {
							width : op.richMode.width,
							height : op.richMode.height,
							okClick : function(){}

						});
				Ccay.UI.dialog._caller = input;
			}
		}
	}
	
	Ccay.UI.Selector = {
			register : function(panel, fnGetSelected, fnSetSelected) {
				if (fnGetSelected) {
					var btn, parent = $(panel).parents('.ccay-selector');
					if (parent.length) {
						btn = parent.find('.ccay-selector-operate > input');
						if (fnSetSelected)
							btn.data('fnSetSelected', fnSetSelected);
					} else {
						parent = $(panel).parents('.ccay-dialog-body').next();
						btn = parent.children('input.ccay-dialog-button:first');
					}

					btn.click(function() {
								var returns = fnGetSelected();
								if (returns) {
									var selector, input;
									if (btn.hasClass('ccay-dialog-button')) {
										if (Ccay.UI.dialog._caller) {
											input = Ccay.UI.dialog._caller;
											selector = dropdown.getSelector(input);
											Ccay.UI.dialog._caller = null;
											$(this).next().click();
										}
									} else {
										selector = $(this).parents('.ccay-selector');
										input = dropdown.getInput(selector);
									}
									Ccay.UI.Selector.selected(returns, selector, input)
								}
							});
				}
			},
			selected : function(returns, selector, input) {
				var op = selector.data('op'), value, text;
				if (returns.length) {
					var data = Ccay.UI.getValueText(returns, op);
					value = data.value;
					text = data.text;
				} else {
					value = returns[op.valueField];
					text = returns[op.valueField];
				}
				dropdown.selected(op, value, text, returns, selector, input);
				input.focus();
			},
			getInput : function(panel) {
				var selector = $(panel).parents('.ccay-selector');
				if (selector.length)
					return dropdown.getInput(selector);
				else if (Ccay.UI.dialog._caller)
					return Ccay.UI.dialog._caller;
			},
			setGridSelected : function(grid) {
				var grid = $(grid), input = Ccay.UI.Selector.getInput(grid);
				if (input) {
					var value = input.dataValue(), op = $(input.data('selector')).data('op'), 
						gridManager = grid.getCcayGridManager();
					gridManager.selectedRows = [];
					
					Ccay.UI.matchText(value, grid.find('.gt-body-div .ccay-selector-value'),
							function(result, item) {
								var tr = item.parents('tr.gt-row');
								gridManager.checkRow(tr[0], result);
							}, op.valueSplit, null, null, 1);
				}
			}
		}
})(jQuery);
